You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 07:57:13