Redux Persist非可序列化值问题解惑:为何他人无需特殊配置?
我最初尝试用以下代码持久化Redux Store:
import AsyncStorage from '@react-native-async-storage/async-storage' import { persistStore, persistReducer } from 'redux-persist'; import { configureStore, combineReducers } from "@reduxjs/toolkit"; import {searchReducer} from "./search/searchSlice" import {userReducer} from "./user/userSlice" const combinedReducers = combineReducers({ search: searchReducer, user: userReducer }) const persistedReducer = persistReducer({ key: "root", storage: AsyncStorage, whitelist: ['user'], blacklist: ['search'] }, combinedReducers) export const store = configureStore({ reducer: persistedReducer }) export const persistor = persistStore(store) export type RootState = ReturnType<typeof store.getState> export type AppDispatch = typeof store.dispatch
运行后出现错误:
R A non-serializable value was detected in an action, in the path: `register`. Value: [Function register]
查了GitHub Issues和官方文档后,修改代码解决了问题:
import AsyncStorage from '@react-native-async-storage/async-storage' import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER, } from 'redux-persist' import { configureStore, combineReducers } from '@reduxjs/toolkit' import { searchReducer } from './search/searchSlice' import { userReducer } from './user/userSlice' const combinedReducers = combineReducers({ search: searchReducer, user: userReducer, }) const persistedReducer = persistReducer( { key: 'root', storage: AsyncStorage, whitelist: ['user'], blacklist: ['search'], }, combinedReducers ) export const store = configureStore({ reducer: persistedReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: { ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER], }, }), }) export const persistor = persistStore(store) export type RootState = ReturnType<typeof store.getState> export type AppDispatch = typeof store.dispatch
但我发现很多教程(包括付费React课程)用类似的初始代码却没报错,想知道为什么他们的代码能正常运行,我的却不行?
核心原因集中在版本差异与默认配置变化上:
Redux Toolkit(RTK)序列化检查规则更新
早期RTK版本的configureStore默认中间件对序列化的检查较为宽松,甚至默认忽略了redux-persist的内部action。但后续版本(如1.8.x及以后)强化了序列化验证逻辑,默认会校验所有action的payload是否可序列化,而redux-persist的REGISTER等内部action携带了函数类型参数,触发了这个检查。redux-persist与RTK的兼容性适配调整
旧版redux-persist未明确暴露FLUSH、REHYDRATE等action类型常量,且当时RTK的默认配置已包含对这些action的忽略。但新版本的redux-persist要求用户手动将这些action加入序列化检查的忽略列表,否则就会抛出错误。教程时效性不足
多数教程基于旧版本的RTK和redux-persist制作,当时的默认配置无需手动添加忽略规则即可正常运行。随着库的迭代,官方为提升应用稳定性调整了默认行为,但教程未同步更新内容。项目依赖版本不一致
你当前项目安装的RTK和redux-persist版本较新,而教程使用的是旧版本组合。比如教程用RTK 1.7.x及以下、redux-persist 6.0.x早期版本时不会触发该错误;而你使用的新版本组合则必须手动配置忽略规则。
内容的提问来源于stack exchange,提问作者Kos-Mos

