如何使用Redux Toolkit搭配redux-persist清除所有持久化存储的state
Redux Toolkit 配合 redux-persist 实现purge清空状态完整示例
官方示例里的
customEntityAdapter是通过RTK提供的createEntityAdapter方法创建的实体适配器实例,仅在你使用createEntityAdapter管理规范化数据时需要,普通slice的状态清空不需要使用这个,直接重置state对应字段即可。
步骤1:安装依赖
npm install @reduxjs/toolkit redux-persist # 或者用yarn yarn add @reduxjs/toolkit redux-persist
步骤2:普通slice(不使用EntityAdapter)配置示例
大多数场景下我们使用普通slice即可,不需要用到实体适配器:
// src/features/user/userSlice.js import { createSlice } from '@reduxjs/toolkit' import { PURGE } from 'redux-persist' const initialState = { name: '', token: '', userId: null } const userSlice = createSlice({ name: 'user', initialState, reducers: { setUserInfo: (state, action) => { const { name, token, userId } = action.payload state.name = name state.token = token state.userId = userId } }, extraReducers: (builder) => { builder.addCase(PURGE, () => { // 直接返回初始状态即可完成当前slice的状态清空 return initialState }) } }) export const { setUserInfo } = userSlice.actions export default userSlice.reducer
步骤3:使用createEntityAdapter的slice配置示例
如果你用到了实体适配器管理规范化列表数据,就可以直接用适配器自带的方法清空状态:
// src/features/posts/postsSlice.js import { createSlice, createEntityAdapter } from '@reduxjs/toolkit' import { PURGE } from 'redux-persist' // 此处创建的postsAdapter就是官方示例中的customEntityAdapter const postsAdapter = createEntityAdapter({ sortComparer: (a, b) => b.date.localeCompare(a.date) }) // 用适配器生成初始state const initialState = postsAdapter.getInitialState() const postsSlice = createSlice({ name: 'posts', initialState, reducers: { addPost: postsAdapter.addOne, updatePost: postsAdapter.updateOne, removePost: postsAdapter.removeOne }, extraReducers: (builder) => { builder.addCase(PURGE, (state) => { // 调用适配器的removeAll方法清空所有实体数据 postsAdapter.removeAll(state) }) } }) export const { addPost, updatePost, removePost } = postsSlice.actions export default postsSlice.reducer
步骤4:store与persist核心配置
大部分purge报错都是因为这一步配置缺失导致的:
// src/app/store.js import { configureStore, combineReducers } from '@reduxjs/toolkit' import storage from 'redux-persist/lib/storage' import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from 'redux-persist' // 引入自定义的slice reducer import userReducer from '../features/user/userSlice' import postsReducer from '../features/posts/postsSlice' // 合并所有reducer const rootReducer = combineReducers({ user: userReducer, posts: postsReducer }) const persistConfig = { key: 'root', version: 1, storage, // 可选配置:指定不需要持久化的reducer // blacklist: ['someNonPersistReducer'] } const persistedReducer = persistReducer(persistConfig, rootReducer) export const store = configureStore({ reducer: persistedReducer, // 必须添加该中间件配置,否则调用persist相关action会触发序列化报错 middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: { ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER], }, }), }) export const persistor = persistStore(store)
步骤5:调用purge清空持久化数据
示例为React组件中触发退出登录清空所有状态的场景:
import { persistor } from '../app/store' function LogoutButton() { const handleLogout = async () => { // 调用purge清空所有持久化存储的数据,会自动触发所有slice监听PURGE的逻辑 await persistor.purge() // 后续可添加重置路由、刷新页面等逻辑 window.location.href = '/login' } return <button onClick={handleLogout}>退出登录</button> }
常见问题排查
- 调用purge时报序列化相关错误:检查store配置中是否正确添加了
serializableCheck忽略redux-persist的相关action - purge后状态没有清空:检查对应slice的extraReducers是否正确监听了PURGE action,正常返回初始状态或者调用adapter的removeAll方法
- 仅需要清空单个slice状态的场景,不需要调用persistor.purge,可以直接在slice里自定义重置reducer,调用对应action即可
内容的提问来源于stack exchange,提问作者Chris David
相关产品推荐
相关产品推荐

