Redux Toolkit中Reducer状态更新后统一执行回调的实现方案
问题描述
我希望优化代码实现效率,以下是我的Redux Toolkit切片完整代码示例:
import { createSlice } from '@reduxjs/toolkit'; import { setCookie } from '../../utils/storageHandler'; const initialState = { name: null, age: null } const formSlice = createSlice({ name: 'formSlice', initialState: initialState, reducers: { setName(state, action) { state.name = action.payload; setCookie('name', action.payload); }, setAge(state, action) { state.age = action.payload; setCookie('age', action.payload); } } }); export const { setName, setAge, } = formSlice.actions; export default formSlice.reducer;
我不想在每个reducer中重复编写setCookie(name, value)代码,希望只写一次,在每个reducer函数执行后自动调用。
我会传递如下格式的payload:
{type: string, value: string}
然后在每个reducer执行后运行回调,调用setCookie(...)函数,如下所示:
setCookie(action.payload.type, action.payload.value)
理想情况下,我希望在切片内这样编写代码:
const formSlice = createSlice({ name: 'formSlice', initialState: initialState, reducers: { setName(state, action) { state.name = action.payload; }, setAge(state, action) { state.age = action.payload; } }, callback(action) { setCookie(action.payload.type, action.payload.value) } });
是否有办法实现这种需求?或者有没有其他思路?
我的核心目标是将表单值存储在cookie中,以便客户每次访问时自动预填注册表单。当前没有认证机制,且我不会在组件中编写cookie存储逻辑!
解决方案
方法一:封装通用更新逻辑(最简单直接)
可以写一个通用的状态更新函数,同时包含cookie存储逻辑,在所有表单字段的reducer中复用:
import { createSlice } from '@reduxjs/toolkit'; import { setCookie } from '../../utils/storageHandler'; const initialState = { name: null, age: null } // 统一处理状态更新和cookie存储 const updateFormField = (state, action) => { const { type: fieldName, value } = action.payload; // 更新redux状态 state[fieldName] = value; // 写入cookie setCookie(fieldName, value); }; const formSlice = createSlice({ name: 'formSlice', initialState, reducers: { setName: updateFormField, setAge: updateFormField } }); export const { setName, setAge } = formSlice.actions; export default formSlice.reducer;
调用action时传入约定格式的payload即可,比如setName({type: 'name', value: '张三'}),无需在每个reducer中重复写cookie逻辑。
方法二:用Redux中间件分离逻辑
如果希望把状态更新和cookie存储完全解耦,可以自定义一个中间件,监听该切片的所有action并自动处理cookie:
// formCookieMiddleware.js import { setCookie } from '../utils/storageHandler'; export const formCookieMiddleware = store => next => action => { // 只处理formSlice下的action if (action.type.startsWith('formSlice/')) { const { type: fieldName, value } = action.payload; setCookie(fieldName, value); } return next(action); };
然后在store配置中加入这个中间件:
import { configureStore } from '@reduxjs/toolkit'; import formReducer from './formSlice'; import { formCookieMiddleware } from './formMiddleware'; export const store = configureStore({ reducer: { form: formReducer }, middleware: getDefaultMiddleware => getDefaultMiddleware().concat(formCookieMiddleware) });
此时切片只需专注处理状态更新:
import { createSlice } from '@reduxjs/toolkit'; const initialState = { name: null, age: null } const formSlice = createSlice({ name: 'formSlice', initialState, reducers: { setName(state, action) { state.name = action.payload.value; }, setAge(state, action) { state.age = action.payload.value; } } }); export const { setName, setAge } = formSlice.actions; export default formSlice.reducer;
方法三:利用action的prepare函数
可以给每个action配置统一的prepare函数,在action创建阶段完成cookie存储,reducer只负责更新状态:
import { createSlice } from '@reduxjs/toolkit'; import { setCookie } from '../../utils/storageHandler'; const initialState = { name: null, age: null } // 通用prepare函数 const prepareFieldUpdate = (fieldName, value) => { setCookie(fieldName, value); return { payload: { type: fieldName, value } }; }; const formSlice = createSlice({ name: 'formSlice', initialState, reducers: { setName: { reducer(state, action) { state.name = action.payload.value; }, prepare: (value) => prepareFieldUpdate('name', value) }, setAge: { reducer(state, action) { state.age = action.payload.value; }, prepare: (value) => prepareFieldUpdate('age', value) } } }); export const { setName, setAge } = formSlice.actions; export default formSlice.reducer;
这种方式下组件调用更简洁,比如setName('张三')即可自动完成cookie存储和状态更新。
内容的提问来源于stack exchange,提问作者KKK
相关产品推荐
相关产品推荐

