Redux报错Invariant failed检测到状态突变,用扩展运算符仍报错如何解决?
Redux 状态突变报错排查解决方法
报错Error: Invariant failed: A state mutation was detected between dispatches说明你在Redux dispatch的间隙,直接修改了store中的状态引用对象,不是通过reducer生成新状态的方式更新。你当前的reducer写法本身没有问题,按以下步骤排查即可:
排查步骤
- 先检查所有使用
getPeopleName状态的业务代码:
只要你在组件、工具函数中直接修改了这个对象的内部属性(比如this.props.getPeopleName.name = 'xxx'、delete this.props.getPeopleName.id这类操作),就会直接修改store中的状态,触发该报错。所有状态修改必须通过dispatch新的action走reducer更新,不能直接修改引用类型的状态属性。 - 检查axios响应拦截器逻辑:
如果你给ApiService封装的axios加了全局响应拦截器,且拦截器中是直接修改resp.data的原对象(比如给返回值加通用状态码、附加字段),那么这个被修改后的引用对象存入store后,拦截器的修改操作就会被检测为状态突变。拦截器修改返回值前先对resp.data做一次拷贝再操作即可。 - 临时在reducer中做深拷贝验证根因:
你可以先把reducer中getPeopleName :action.payload的写法改成深拷贝赋值,测试报错是否消失:
如果修改后报错消失,就可以确定是// 单层对象用浅拷贝即可 getPeopleName: {...action.payload} // 多层嵌套对象用深拷贝,可使用lodash.cloneDeep或者JSON序列化方式 getPeopleName: JSON.parse(JSON.stringify(action.payload))action.payload对应的引用对象在其他地方被修改导致的问题,反向排查持有该引用的代码位置即可。 - 利用不可变检测中间件定位问题:
如果你项目中引入了redux-immutable-state-invariant中间件做不可变检测,可以直接在该中间件的报错逻辑处打断点,它会返回具体被修改的属性路径,根据路径直接定位修改代码即可。
内容的提问来源于stack exchange,提问作者Sai Krishnadas
相关产品推荐
相关产品推荐

