Zustand如何实现类似useEffect的状态联动更新?
解决方案
1. 封装统一的setActiveRecord方法
在Zustand store里定义一个专门处理activeRecord更新的内部方法,每次调用它时自动同步originalRecord,所有需要更新activeRecord的场景都复用这个方法,彻底避免重复代码。
示例代码:
import { create } from 'zustand'; const useRecordStore = create((set, get) => { // 内部封装:更新activeRecord同时同步originalRecord const setActiveRecord = (newActiveRecord) => { set({ activeRecord: newActiveRecord, // 深拷贝按需替换,比如用structuredClone处理嵌套对象 originalRecord: { ...newActiveRecord } }); }; return { records: [], activeRecord: null, recordIndex: 0, recordCount: 0, originalRecord: null, setRecords: (records) => { const newActiveRecord = records[get().recordIndex]; set({ records: records, recordCount: records.length }); // 调用封装方法完成同步 setActiveRecord(newActiveRecord); }, // 其他需要切换activeRecord的场景也复用这个方法 switchActiveRecord: (index) => { set({ recordIndex: index }); setActiveRecord(get().records[index]); } }; });
2. 用Zustand订阅监听activeRecord变化
这种方式完全复刻你原来useEffect的逻辑:监听activeRecord的所有变化,一旦更新就自动同步originalRecord,不管是哪个方法触发的activeRecord变更都能生效。
示例代码:
import { create } from 'zustand'; const useRecordStore = create((set, get) => { // 监听activeRecord的变化,自动同步originalRecord get().subscribe( (state) => state.activeRecord, (newActiveRecord) => { if (newActiveRecord) { set({ originalRecord: { ...newActiveRecord } }); } } ); return { records: [], activeRecord: null, recordIndex: 0, recordCount: 0, originalRecord: null, setRecords: (records) => { set({ records: records, activeRecord: records[get().recordIndex], recordCount: records.length }); // 无需手动写同步逻辑,订阅会自动处理 }, switchActiveRecord: (index) => { set({ recordIndex: index, activeRecord: get().records[index] }); // 同样无需手动同步 } }; });
关键提醒
如果activeRecord是嵌套对象,不要用浅拷贝{ ... },改用structuredClone(newActiveRecord)来创建深副本,避免后续修改activeRecord时意外污染originalRecord。
内容的提问来源于stack exchange,提问作者Ricky
相关产品推荐
相关产品推荐

