MERN电商项目接入redux-persist后读取user属性报错求助
修复方案
1. 修复store.js导出逻辑错误(核心问题)
你当前导出的store是一个返回store实例的函数,而非直接的store实例,同时创建persistor时传入的是configureStore构造函数而非实际的store实例,导致Provider没有拿到正确的store,useSelector无法读取state数据。
替换store.js全部代码为:
import { configureStore, combineReducers } from "@reduxjs/toolkit"; import cartReducer from "./cartRedux"; import userReducer from "./userRedux"; import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER, } from "redux-persist"; import storage from "redux-persist/lib/storage"; const persistConfig = { key: "root", version: 1, storage, }; const rootReducer = combineReducers({ user: userReducer, cart: cartReducer }) const persistedReducer = persistReducer(persistConfig, rootReducer); // 直接创建并导出store实例 export const store = configureStore({ reducer: persistedReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: { ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER], }, }) }) // 用实际store实例创建persistor export let persistor = persistStore(store);
2. 修复requestMethods.js token读取逻辑错误
你当前在模块初始化阶段就直接读取localStorage获取token,此时可能redux-persist还未完成数据恢复,或者用户未登录时persist:root/user字段不存在,直接读取会抛出空指针错误。同时初始化时固定的token不会随用户登录状态更新,后续请求会一直携带旧token。
替换requestMethods.js全部代码为:
import axios from "axios"; const BASE_URL = "http://localhost:5000/api/"; export const publicRequest = axios.create({ baseURL: BASE_URL, }); export const userRequest = axios.create({ baseURL: BASE_URL, }); // 添加请求拦截器动态获取最新token userRequest.interceptors.request.use((config) => { const persistRoot = localStorage.getItem('persist:root') if (!persistRoot) return config try { const rootState = JSON.parse(persistRoot) if (rootState.user) { const userState = JSON.parse(rootState.user) const token = userState.currentUser?.accessToken if (token) { config.headers.token = `Bearer ${token}` } } } catch (e) {} return config })
3. TypeScript类型报错修复(可选,针对TS项目)
如果项目使用TypeScript,还需要定义全局RootState类型解决Property 'user' does not exist on type 'DefaultRootState'报错:
- 在
store.js末尾添加类型导出:
export type RootState = ReturnType<typeof store.getState>
- 使用
useSelector时指定state类型:
const user = useSelector((state: RootState) => state.user.currentUser);
4. 修复App.jsx冗余代码
你在Login路由下重复写了两次Login组件,登录跳转逻辑完成后多余的Login组件仍会渲染,修改对应路由代码:
<Route path="/login"> {user ? <Redirect to="/"/> : <Login/>} </Route> <Route path="/register"> {user ? <Redirect to="/"/> : <Register/>} </Route>
内容的提问来源于stack exchange,提问作者Marius Petrut
相关产品推荐
相关产品推荐

