React+Redux报错:Actions must be plain objects 问题排查求助
解决Redux Action报错:Actions must be plain objects
这个问题我碰到过,核心原因是Redux对Action的类型有严格要求——必须是普通JavaScript对象,而你用new AuthenticatedStateAction()创建的是类实例,不符合Redux内部的检查规则。
为什么类实例不行?
虽然你的AuthenticatedStateAction类实现了Action接口,也包含type和payload属性,但JavaScript的类实例本质上是带有原型链的对象。Redux内部会通过判断Object.prototype.toString.call(action)是否等于[object Object]来确认是不是普通对象,类实例显然不满足这个条件,所以会抛出那个错误。
解决方案
下面提供几种可行的修正方式,按推荐程度排序:
1. 改用工厂函数返回普通对象(最符合Redux原生规范)
把类替换成一个返回纯对象的函数:
// 定义Action创建函数 function createAuthenticatedStateAction(payload: boolean): Action { return { type: 'Shared: SetAuthenticatedState Action', payload }; } // 在mapDispatchToProps中使用 const mapDispatchToProps = (dispatch: Function) => ({ authenticated: (props: ChatProps) => { return dispatch(createAuthenticatedStateAction(!props.isAuthenticated)); } })
2. 把类实例转为普通对象分发(临时 workaround)
如果暂时不想改类的结构,可以在分发前将实例解构为普通对象:
const mapDispatchToProps = (dispatch: Function) => ({ authenticated: (props: ChatProps) => { // 用解构把类实例转为纯对象 return dispatch({ ...new AuthenticatedStateAction(!props.isAuthenticated) }); } })
不过这种方式不够优雅,不推荐长期使用。
3. 使用Redux Toolkit的createAction(官方推荐)
Redux Toolkit是官方推出的工具集,能简化很多Redux开发流程,它的createAction会自动生成符合要求的Action创建函数:
import { createAction } from '@reduxjs/toolkit'; // 生成Action创建函数 const authenticatedStateAction = createAction<boolean>('Shared: SetAuthenticatedState Action'); // 在mapDispatchToProps中使用 const mapDispatchToProps = (dispatch: Function) => ({ authenticated: (props: ChatProps) => { return dispatch(authenticatedStateAction(!props.isAuthenticated)); } })
Redux Toolkit还能帮你处理异步Action、Reducer编写等问题,建议直接迁移到这个工具集开发。
总结
Redux的Action必须是无原型链的普通对象,类实例不符合这个要求。最稳妥的方式是用工厂函数或Redux Toolkit来创建Action,避免手动实例化类。
内容的提问来源于stack exchange,提问作者Prafull Dhadkar
相关产品推荐
相关产品推荐

