Redux Store组件出现重复副本问题,请求排查错误原因
问题排查:Redux Slice与Persist配置导致状态重复问题
执行dispatch更新状态后,每个组件中都出现了所有Slice的变量副本,问题根源及解决方案如下:
1. User Slice 代码
import { createSlice } from '@reduxjs/toolkit' const initialState = { username: null, token: null } export const userSlice = createSlice({ name: 'user', initialState, reducers: { login: (state, action) => { state.username = action.payload.username state.token = action.payload.token }, logout: (state) => { state.username = null state.token = null }, }, }) export const { login, logout } = userSlice.actions export default userSlice.reducer
2. Profile Slice 代码
import { createSlice } from '@reduxjs/toolkit' const initialState = { name: null, family: null, phoneNumber: null } export const profileSlice = createSlice({ name: 'profile', initialState, reducers: { setProfile: (state, action) => { state.name = action.payload.name state.family = action.payload.family state.phoneNumber = action.payload.phoneNumber }, deleteProfile: (state) => { state.name = null state.family = null state.phoneNumber = null }, }, }) export const { setProfile, deleteProfile } = profileSlice.actions export default profileSlice.reducer
3. General Slice 代码
import { createSlice } from '@reduxjs/toolkit' const initialState = { isPreparing: false, isLogedIn: false, } export const generalSlice = createSlice({ name: 'general', initialState, reducers: { setIsPreparing: (state, action) => { state.isPreparing = action.payload.isPreparing }, setIsLogedIn: (state, action) => { state.isLogedIn = action.payload.isLogedIn }, }, }) export const { setIsPreparing, setIsLogedIn } = generalSlice.actions export default generalSlice.reducer
4. Store 配置代码
import { configureStore } from '@reduxjs/toolkit' import userReducer from './userSlice' import profileReducer from './profileSlice' import generalReducer from './generalSlice'; import storage from 'redux-persist/lib/storage'; import { persistReducer, persistStore } from 'redux-persist'; import thunk from 'redux-thunk'; const persistConfig = { key: 'root', storage, } const persistedUserReducer = persistReducer(persistConfig, userReducer) const persistedProfileReducer = persistReducer(persistConfig, profileReducer) const persistedGeneralReducer = persistReducer(persistConfig, generalReducer) export const store = configureStore({ reducer: { user: persistedUserReducer, profile: persistedProfileReducer, general: persistedGeneralReducer, }, middleware: [thunk], }) export const persistor = persistStore(store)
5. 状态更新的Dispatch代码
dispatch(login({ username: username, token: response.data.key })) dispatch(setIsLogedIn({ isLogedIn: true })) dispatch(setIsPreparing({ isPreparing: true }))
问题根源
你给三个独立的Slice都配置了同一个persistConfig(key为root),导致redux-persist会将三个Slice的状态都写入到本地存储的同一个root键下,状态互相覆盖、合并,最终每个Slice的状态中都会混入其他Slice的字段,组件获取状态时就会看到所有变量的副本。
解决方案
方案一:使用根Reducer统一持久化(推荐)
合并所有子Reducer为一个根Reducer,仅对根Reducer做持久化处理:
import { configureStore, combineReducers } from '@reduxjs/toolkit' import userReducer from './userSlice' import profileReducer from './profileSlice' import generalReducer from './generalSlice'; import storage from 'redux-persist/lib/storage'; import { persistReducer, persistStore } from 'redux-persist'; import thunk from 'redux-thunk'; const persistConfig = { key: 'root', storage, } // 合并所有子Reducer为根Reducer const rootReducer = combineReducers({ user: userReducer, profile: profileReducer, general: generalReducer, }) // 仅持久化根Reducer const persistedReducer = persistReducer(persistConfig, rootReducer) export const store = configureStore({ reducer: persistedReducer, middleware: [thunk], }) export const persistor = persistStore(store)
方案二:为每个Slice配置独立的持久化Key
如果需要单独控制每个Slice的持久化策略,给每个Slice分配唯一的key:
import { configureStore } from '@reduxjs/toolkit' import userReducer from './userSlice' import profileReducer from './profileSlice' import generalReducer from './generalSlice'; import storage from 'redux-persist/lib/storage'; import { persistReducer, persistStore } from 'redux-persist'; import thunk from 'redux-thunk'; // 为每个Slice配置独立的persist配置 const userPersistConfig = { key: 'user', storage } const profilePersistConfig = { key: 'profile', storage } const generalPersistConfig = { key: 'general', storage } const persistedUserReducer = persistReducer(userPersistConfig, userReducer) const persistedProfileReducer = persistReducer(profilePersistConfig, profileReducer) const persistedGeneralReducer = persistReducer(generalPersistConfig, generalReducer) export const store = configureStore({ reducer: { user: persistedUserReducer, profile: persistedProfileReducer, general: persistedGeneralReducer, }, middleware: [thunk], }) export const persistor = persistStore(store)
内容的提问来源于stack exchange,提问作者Sadegh Eskandari
相关产品推荐
相关产品推荐

