Redux Toolkit状态在页面刷新/路由跳转后重置如何解决
问题原因
- Redux 默认是内存级存储:所有状态只保存在当前页面的JS运行内存中,一旦触发整页刷新、地址栏手动跳转导致页面全量重载,JS内存被回收,状态自然会回到slice中定义的初始值,这是Redux的默认设计,不是代码bug。
- 客户端路由跳转丢状态的核心原因:如果是用前端路由做无刷新跳转时状态也重置,基本都是Store挂载位置错误导致的。检查
<Provider store={store}>是不是写在了某个页面级组件内部,而不是应用最外层根组件。跳页时页面组件卸载重建,会连带创建全新的Store实例,之前存的状态自然全部丢失。
解决方案
1. 修复基础挂载问题
确保Redux的Provider组件包裹在整个应用的最外层,全局只初始化一次Store实例,不要在子页面、业务组件里重复嵌套Provider。
2. 持久化需要跨刷新保留的状态
要让登录态这类需要跨刷新保留的状态不丢失,使用redux-persist把指定状态同步到本地存储(localStorage/sessionStorage),应用加载时自动把本地存储的状态回填到Redux即可。
操作步骤:
- 安装依赖:
npm install redux-persist - 修改Store配置文件(index.ts):
import { configureStore, combineReducers } from "@reduxjs/toolkit"; import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER, } from "redux-persist"; import storage from "redux-persist/lib/storage"; import authStateSlice from "redux/authStateSlice"; import deviceTypeReducer from "redux/deviceTypeSlice"; import userDataSlice from "redux/userDataSlice"; // 持久化规则配置 const persistConfig = { key: "app_root", storage, // 只有写在whitelist里的slice才会被持久化,不要把不需要长期存储的状态加入 whitelist: ["isLogin", "userData"], }; const rootReducer = combineReducers({ isMobile: deviceTypeReducer, isLogin: authStateSlice, userData: userDataSlice, }); const persistedReducer = persistReducer(persistConfig, rootReducer); const store = configureStore({ reducer: persistedReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: { // 忽略redux-persist内置的action类型,避免序列化校验报错 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; export default store;
- 修改根组件渲染逻辑,加入持久化加载门限组件:
import { Provider } from "react-redux"; import { PersistGate } from "redux-persist/integration/react"; import store, { persistor } from "你的redux store文件实际路径"; // 应用根节点渲染 root.render( <Provider store={store}> <PersistGate loading={null} persistor={persistor}> <App /> </PersistGate> </Provider> );
额外代码问题提醒
你贴的signin.tsx里有个隐藏运行时bug:catch块中写的throw new Error(err),这里的err是上一个响应错误判断块里的局部变量,catch作用域内无法访问,运行到这里会直接报引用错误,记得改成使用catch接收的error对象。
内容的提问来源于stack exchange,提问作者bluepuper
相关产品推荐
相关产品推荐

