代码之家  ›  专栏  ›  技术社区  ›  Tom Troughton

对于在外部包中定义的操作,无法读取redux存储中“未定义”的属性“type”

  •  1
  • Tom Troughton  · 技术社区  · 6 年前

    作为我正在进行的学习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';
    

    然后在我的消费项目中,我的默认减速机如下所示:

    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 1 hit 2 )显示,但随后出现以下错误:

    Uncaught 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包之外,我看不出我在做什么不同。因为actions和reducer实际上都不依赖redux,所以我的npm包本身不依赖于 react-redux . 有问题吗?如果还有什么我可以分享的帮助你帮我的,就告诉我。就像我说的,我对这一切还很陌生,很明显有些事情我做得不对!

    1 回复  |  直到 6 年前
        1
  •  3
  •   cheekujha    6 年前

    问题可能在于 希德斯纳克巴 功能

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

    函数试图返回 对象字面量 箭头函数 . 这个总会回来的 未定义 . 因为解析器不会将这两个大括号解释为对象文本,而是将其解释为块语句。因此,错误无法读取未定义的属性“type”,因为存储区需要属性类型为的操作。

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

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

    括号强制将其解析为对象文本。希望这有帮助