Redux存储中的“无法读取未定义的属性'类型'的未定义”,用于外部包中定义的操作

时间:2018-07-29 11:09:36

标签: javascript reactjs npm redux react-redux

作为我正在进行的学习React项目的一部分(我本人是ASP.NET专家),我遇到了这个问题。我有一套React应用程序,我想在其中使用一些常见的UI元素,因此我试图将它们分解成一个单独的npm包。对于共享组件本身,它运行良好。

但是,其中一些组件依赖redux动作来操作,因此我尝试将这些动作和reducer函数捆绑到外部程序包中。这是我的actions\index.js的简化版:

export const SNACKBAR_MESSAGE = "SNACKBAR_MESSAGE";
export const SNACKBAR_HIDE = "SNACKBAR_HIDE";

export function showSnackBarMessage(message) {
    console.log('hit 1');
    return (dispatch, getState) => {
        console.log('hit 2');
        dispatch(hideSnackBar());
        dispatch({
            type: SNACKBAR_MESSAGE,
            message: message
        });
    }
}

export const hideSnackBar = () => {
    type: SNACKBAR_HIDE
};

这是reducer\index.js

import { 
    SNACKBAR_MESSAGE,
    SNACKBAR_HIDE
} from "../actions";

const initialState = {
    snackBarMessage: null,
    snackBarVisible: false
};

export default function UiReducer(state = initialState, action) {
    switch(action.type) {
        case SNACKBAR_MESSAGE:
            return Object.assign({}, state, { 
                snackBarMessage: action.message,
                snackBarVisible: true
            });
        case SNACKBAR_HIDE:
            return Object.assign({}, state, { 
                snackBarMessages: '',
                snackBarVisible: false
            });
        default:
            return state;
    }
}

这是在原始项目的一部分时可以正常工作的相同代码。这些通过我的包的入口点文件导出,如下所示:

// Reducer
export { default as uiReducer } from './reducer';

// Actions
export { showSnackBarMessage as uiShowPrompt } from './actions';
export { hideSnackBar as uiHidePrompt } from './actions';

然后在我的消耗项目中,我的默认reducer如下所示:

import { routerReducer } from 'react-router-redux';
import { combineReducers } from 'redux';
import { uiReducer } from 'my-custom-ui-package';
// Import local reducers

const reducer = combineReducers(
  {
    // Some local reducers
    ui: uiReducer
  }
);

export default reducer;

问题是当我尝试调度从外部程序包导入的这些操作之一时。我包括动作,例如import { uiShowPrompt } from "my-custom-ui-package";并像dispatch(uiShowPrompt("Show me snackbar"));一样分发它,然后我看到显示了两个控制台消息(hit 1hit 2),但是出现了以下错误:

  

未捕获的TypeError:无法读取未定义的属性'type'

at store.js:12
at dispatch (applyMiddleware.js:35)
at my-custom-ui-package.js:1
at index.js:8
at middleware.js:22
at store.js:15
at dispatch (applyMiddleware.js:35)
at auth.js:28
at index.js:8
at middleware.js:22

商店本身看起来像这样:

import { createStore, combineReducers, applyMiddleware, compose } from "redux";
import thunk from 'redux-thunk';
import { browserHistory } from "react-router";
import {
  syncHistoryWithStore,
  routerReducer,
  routerMiddleware
} from "react-router-redux";
import reducer from "./reducer";

const loggerMiddleware = store => next => action => {
    console.log("Action type:", action.type);
    console.log("Action payload:", action.payload);
    console.log("State before:", store.getState());
    next(action);
    console.log("State after:", store.getState());
};

const initialState = {};

const createStoreWithMiddleware = compose(
  applyMiddleware(
    loggerMiddleware, 
    routerMiddleware(browserHistory), 
    thunk)
)(createStore);

const store = createStoreWithMiddleware(reducer, initialState);

export default store;

恐怕我不明白这个错误。除了本质上将相同的代码从本地项目移至npm软件包之外,我看不到我在做什么。由于动作和减速器实际上都不依赖于redux,因此我的npm包本身并不依赖于react-redux。那是问题吗?如果还有其他我想分享的内容,可以帮助您,请告诉我。就像我说的那样,我仍然对这一切还很陌生,因此很明显我有些不对劲!

2 个答案:

答案 0 :(得分:3)

问题可能出在 hideSnackBar 函数的声明

Fragment3 fragment3 = new Fragment3();
getSupportFragmentManager().beginTransaction().add(R.id.content, fragment3).addToBackStack(null).commit();

此函数尝试从箭头函数返回对象文字。这将始终返回 undefined 。由于解析器不会将两个大括号解释为对象文字,而是将其解释为语句块。因此,错误“无法读取未定义为存储的未定义属性'类型'期望具有属性类型的操作。

替换这样的代码,看看它是否有效。

export const hideSnackBar = () => {
    type: SNACKBAR_HIDE
};

括号会强制将其解析为Object Literal。希望这会有所帮助

答案 1 :(得分:0)

我已经把它导出了

export default userReducer();

而不是这样:

export default userReducer;

去掉那个()