引入Redux-Persist后报State.push is not a function错误怎么办
报错原因
State.push is not a function 说明触发addTodos时,当前Todo slice的state不是你定义的数组类型,而是普通对象,问题来自redux-persist的配置错误:
- 你没有通过
combineReducers合并slice生成根reducer,直接把persistReducer包装的单个slice reducer作为根reducer传入store,和你写的whitelist: ["Todo"]逻辑完全不匹配。你预期根state下有Todo字段存放任务数组,但实际根state直接对应slice返回值,persist存取数据时会出现结构错位,水合后state就变成了没有push方法的普通对象。 - 变量命名存在错误:persistReducer返回的是包装后的持久化reducer,不是persistor实例,persistor需要单独调用
persistStore(store)生成。 - 之前错误配置下,localStorage已经存了结构错误的旧缓存,就算改对代码,错误缓存水合进store依然会触发报错。
另外你在addTodos的reducer里手动return state是冗余的,Redux Toolkit内置的Immer会自动处理draft修改,手动return反而可能在边缘场景引发结构覆盖问题。
修复方案
- 重写store配置,正确合并根reducer、生成persistor:
import { combineReducers, configureStore } from "@reduxjs/toolkit"; import { persistReducer, persistStore } from "redux-persist"; import storage from "redux-persist/lib/storage"; // 替换成你的dataSlice实际路径 import dataSlice from "./todoSlice"; const rootReducer = combineReducers({ Todo: dataSlice.reducer, }); const persistConfig = { key: "root", storage, whitelist: ["Todo"], }; const persistedReducer = persistReducer(persistConfig, rootReducer); export const store = configureStore({ reducer: persistedReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false }), }); export const persistor = persistStore(store);
- 修正slice里的addTodos reducer,删掉冗余return:
addTodos: { reducer: (state, action: PayloadAction<IinitialState>) => { state.push(action.payload); }, // prepare部分保持原有逻辑不变 prepare: (title: string, description: string) => ({ payload: { id: uuidv4(), title, description, dateAdded: new Date().getTime(), completed: false, } as IinitialState, }), },
- 清理本地旧缓存:打开浏览器开发者工具-应用面板-LocalStorage,找到你当前站点的存储项,删除所有
persist:开头的缓存条目,刷新页面。 - 确认应用入口已经用PersistGate包裹根组件,保证store水合完成后再渲染页面:
import { Provider } from "react-redux"; import { PersistGate } from "redux-persist/integration/react"; import { store, persistor } from "./store"; root.render( <Provider store={store}> <PersistGate loading={null} persistor={persistor}> <App /> </PersistGate> </Provider> );
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

