如何从Redux的userSlice取值作为cartSlice的初始状态?
问题
我在应用里有两个Redux切片:userSlice和cartSlice,想从userSlice获取userName作为cartSlice中user属性的初始值,但尝试后user始终是undefined。
userSlice.js 代码
import { createSlice } from '@reduxjs/toolkit' const userNameLocalStorage = localStorage.getItem("userRedux") === null ? null : JSON.parse(localStorage.getItem("userRedux")); const initialState = { userName: userNameLocalStorage, } export const userSlice = createSlice({ name: 'users', initialState, reducers: { updateUser: (state, action) => { localStorage.setItem("userRedux", action.payload) state.userName = action.payload; }, logOut: (state) => { window.localStorage.removeItem('userRedux'); state.userName = null; }, }, }) export const { updateUser,logOut } = userSlice.actions export default userSlice.reducer;
cartSlice.js 现有代码
import { createSlice } from '@reduxjs/toolkit' import { userSlice } from './userSlice'; const initialState = { numberOfItems: 0, details: [], total: 0, user: userSlice?.initialState?.userName, } const cartSlice = createSlice({ name: 'cart', initialState, reducers: { }, }) export default cartSlice.reducer;
解决方案
你当前的问题核心是:直接从userSlice对象中读取initialState的方式不可靠——createSlice返回的对象中的initialState无法正确同步运行时从localStorage读取的userName值,甚至可能因为模块加载顺序问题导致读取失败。
下面提供两种可行的解决方式:
方式一:共享初始值读取逻辑
既然userName的初始值来自localStorage,我们可以把这个读取逻辑抽成独立函数,在两个切片中复用:
- 修改
userSlice.js,导出读取localStorage的工具函数:
import { createSlice } from '@reduxjs/toolkit' // 导出共享的读取逻辑 export const getUserNameFromLocalStorage = () => { return localStorage.getItem("userRedux") === null ? null : JSON.parse(localStorage.getItem("userRedux")); } const initialState = { userName: getUserNameFromLocalStorage(), } export const userSlice = createSlice({ name: 'users', initialState, reducers: { updateUser: (state, action) => { localStorage.setItem("userRedux", action.payload) state.userName = action.payload; }, logOut: (state) => { window.localStorage.removeItem('userRedux'); state.userName = null; }, }, }) export const { updateUser, logOut } = userSlice.actions export default userSlice.reducer;
- 在
cartSlice.js中导入该函数,设置user的初始值:
import { createSlice } from '@reduxjs/toolkit' import { getUserNameFromLocalStorage } from './userSlice'; const initialState = { numberOfItems: 0, details: [], total: 0, user: getUserNameFromLocalStorage(), } const cartSlice = createSlice({ name: 'cart', initialState, reducers: { }, }) export default cartSlice.reducer;
方式二:在Store初始化时统一设置预加载状态
如果需要后续userName更新时,cartSlice的user也能同步更新,或者想统一管理初始状态,可以在创建Store时通过preloadedState传入初始值:
// store.js import { configureStore } from '@reduxjs/toolkit' import userReducer from './userSlice' import cartReducer from './cartSlice' // 统一读取localStorage的值 const userNameLocalStorage = localStorage.getItem("userRedux") === null ? null : JSON.parse(localStorage.getItem("userRedux")); export const store = configureStore({ reducer: { users: userReducer, cart: cartReducer, }, // 统一设置两个切片的初始状态 preloadedState: { users: { userName: userNameLocalStorage }, cart: { numberOfItems: 0, details: [], total: 0, user: userNameLocalStorage } } })
如果需要后续同步userName的更新,可以在userSlice的updateUser和logOut reducer中,派发cartSlice的更新动作(需要先在cartSlice中定义对应的reducer)。
内容的提问来源于stack exchange,提问作者Dev Patel
相关产品推荐
相关产品推荐

