如何在Redux Toolkit中获取状态变更值并通过WebSocket发送?
只发送Redux状态中变更字段的几种实现方式
不需要重新配置Redux,给你三个实用方案:
1. 在Slice的Reducer里直接处理
既然每个字段的更新都是通过单独的reducer case触发的,直接在对应case里发送变更的字段就行,逻辑最直接:
import { createSlice } from '@reduxjs/toolkit'; const imgAdjustmentsSlice = createSlice({ name: 'imgAdjustments', initialState: { exposure: 0, iso: 100 }, reducers: { setExposure: (state, action) => { state.exposure = action.payload; // 只发送变更的exposure字段 sendWebSocketMessage({ exposure: action.payload }); }, setIso: (state, action) => { state.iso = action.payload; // 只发送变更的iso字段 sendWebSocketMessage({ iso: action.payload }); } } }); export const { setExposure, setIso } = imgAdjustmentsSlice.actions; export default imgAdjustmentsSlice.reducer;
这种方式把字段更新和发送逻辑绑定在一起,适合字段不多的场景。
2. 在组件中监听单个字段的变化
如果不想把WebSocket逻辑和Redux reducer耦合,就在组件里用useSelector单独监听每个字段,配合useEffect触发发送:
import { useAppSelector } from './store'; import { useEffect } from 'react'; function ImageAdjustPanel() { const exposure = useAppSelector(state => state.imgAdjustments.exposure); const iso = useAppSelector(state => state.imgAdjustments.iso); // 当exposure变化时发送 useEffect(() => { sendWebSocketMessage({ exposure }); }, [exposure]); // 当iso变化时发送 useEffect(() => { sendWebSocketMessage({ iso }); }, [iso]); // 组件的渲染和dispatch逻辑... }
这种方式更灵活,适合需要在组件里做额外判断再发送的场景。
3. 用自定义Redux中间件全局追踪变更
如果有很多字段需要处理,不想重复写发送逻辑,可以写个中间件,自动对比action执行前后的状态,找出变更的字段再发送:
// 自定义中间件 const wsChangeMiddleware = store => next => action => { // 先记录更新前的状态 const prevImgState = store.getState().imgAdjustments; // 执行action,更新状态 const result = next(action); // 获取更新后的状态 const newImgState = store.getState().imgAdjustments; // 找出所有变更的字段 const changed = {}; Object.keys(newImgState).forEach(key => { if (newImgState[key] !== prevImgState[key]) { changed[key] = newImgState[key]; } }); // 有变更就发送 if (Object.keys(changed).length > 0) { sendWebSocketMessage(changed); } return result; }; // 在configureStore中添加中间件 export const store = configureStore({ reducer: { imgAdjustments: imgAdjustmentsReducer }, middleware: getDefaultMiddleware => getDefaultMiddleware().concat(wsChangeMiddleware) });
这种方式适合全局统一处理状态变更的场景,不用在每个reducer或组件里重复写发送代码。
内容的提问来源于stack exchange,提问作者alexander fijjek
相关产品推荐
相关产品推荐

