React Native Redux报non-serializable错误与状态突变问题排查求助
核心问题定位
你存在两个明确的违规用法,触发了Redux Toolkit的默认校验规则:
- 你将
Timer类实例存入了Redux的intervalTimer.timer字段:从补充的报错信息可以看到,这个Timer实例包含事件触发器EventEmitter、on/off函数方法、私有运行时属性,这些都属于不可序列化的值,违反Redux要求state全部为可序列化纯值的规范。 - 你直接修改了存放在Redux中的Timer实例的属性:Timer是引用类型,你在组件内操作计时器修改
_startTime属性时,没有通过reducer做不可变更新,直接修改了state中的引用值,触发了不可变突变检测报错。
报错关联SAVE_REST_SECONDS_INPUT的原因
这个reducer本身逻辑没有问题,它只是修改了字符串类型的restSecondsInput字段。Redux的序列化/不可变检查会在每次dispatch动作后全量扫描state,只是这次刚好触发SAVE_REST_SECONDS_INPUT动作时扫描到了早已存在的timer字段异常,所以才会把该动作关联到报错信息中,和这个reducer本身无关。
修复方案
推荐方案(符合Redux规范)
- 将Timer实例从Redux state中移除:这类带运行时副作用、包含方法和事件绑定的实例不属于需要全局管理的状态,直接存放在组件的
useRef中即可,不需要放到Redux里。 - 仅将需要全局同步的计时器纯状态(比如剩余时长、运行状态、暂停状态等)抽离为字符串/数字/布尔值,存入Redux,Timer实例状态变化时仅dispatch这些纯值更新Redux即可。
临时规避方案(仅调试用,不推荐长期使用)
如果暂时无法重构代码,可以在Redux store配置中关闭对应路径的校验,避免报错:
export const store = configureStore({ reducer: persistedReducer, enhancers: [Reactotron.createEnhancer()], middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: { ignoredPaths: ['intervalTimer.timer'] }, immutableCheck: { ignoredPaths: ['intervalTimer.timer'] } }).concat(expoLogger), devTools: process.env.NODE_ENV !== 'production' })
此前运行正常的原因
Redux Toolkit的序列化检查和不可变突变检查是默认开启的,大概率是你近期升级了Redux Toolkit版本,或者之前配置过关闭校验后来改了配置,才会突然出现报错。另外你已经把intervalTimer加入了持久化黑名单,只是避免了它被存入AsyncStorage,不影响Redux的运行时校验逻辑。
内容的提问来源于stack exchange,提问作者Bruce Mathers
相关产品推荐
相关产品推荐

