“无法读取未定义的属性‘类型’”在 redux 存储中用于外部包中定义的操作

Posted

技术标签:

【中文标题】“无法读取未定义的属性‘类型’”在 redux 存储中用于外部包中定义的操作【英文标题】:"Cannot read property 'type' of undefined" in redux store for action defined in external package 【发布时间】:2019-01-05 20:39:46 【问题描述】:

作为我正在进行的学习 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 1hit 2)显示,但随后出现以下错误:

未捕获的类型错误:无法读取未定义的属性“类型”

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

【问题讨论】:

【参考方案1】:

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

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

这里的函数试图从箭头函数返回一个Object Literal。这将始终返回 undefined。由于解析器不会将两个大括号解释为对象文字,而是作为块语句。因此错误,Cannot read property 'type' of undefined as store 期望具有属性类型的操作。

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

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

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

【讨论】:

完全正确。也谢谢你的详细解释。当然,现在我记得我在创建包时删除了那些括号,以为我在整理!下次我会更小心的。 我遇到了一个类似的问题:***.com/questions/63622988/… - 如果可能,您的意见会有所帮助【参考方案2】:

我已经像这样导出了它

export default userReducer();

不是这样的:

export default userReducer;

摆脱那个()

【讨论】:

【参考方案3】:

发现是使用redux-thunk时接收参数顺序错误的情况。

// wrong argument order
const anAction = () => (getState, dispatch) => ...

// correct one
const anAction = () => (dispatch, getState) => ...

【讨论】:

以上是关于“无法读取未定义的属性‘类型’”在 redux 存储中用于外部包中定义的操作的主要内容,如果未能解决你的问题,请参考以下文章

Redux 和 React-Native:无法读取未定义的属性“类型”

未捕获的类型错误:在开关函数开始时无法读取未定义的属性“类型”

UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性“类型”

运行排毒测试命令时无法读取未定义的属性“类型”

TypeError:无法读取未定义的属性“类型”

使用带有formik的react-select时无法读取未定义的属性“类型”