如何编写Zustand中间件实现调用set()时自动记录当前时间?
实现Zustand自动记录状态修改时间的中间件
你可以通过包装Zustand的set方法来实现这个需求,写一个通用中间件就能让所有状态变更自动带上修改时间,不用每次手动加。
第一步:编写中间件
这个中间件会拦截所有set调用,自动将lastModifiedAt字段合并到更新内容里:
const withLastModified = (create) => (set, get, api) => { // 包装原始set方法 const wrappedSet = (...args) => { // 处理两种set调用方式:直接传对象,或者传函数返回对象 const update = typeof args[0] === 'function' ? (prevState) => ({ ...args[0](prevState), lastModifiedAt: Date.now() }) : { ...args[0], lastModifiedAt: Date.now() }; // 调用原始set方法,传入合并后的更新内容 set(update, ...args.slice(1)); }; // 把包装后的set传给原始create函数 return create(wrappedSet, get, api); };
第二步:在Store中使用中间件
创建store时把中间件传给create函数,之后所有调用set的地方都不用手动处理lastModifiedAt了:
const useStore = create(withLastModified((set) => ({ counter: 1, lastModifiedAt: null, // 初始值设为null,第一次变更后会自动更新 increaseCounter: () => set((s) => ({ counter: s.counter + 1 })), resetCounter: () => set({ counter: 1 }) })));
效果验证
调用increaseCounter或者resetCounter后,store里的lastModifiedAt会自动更新为当前时间戳,完全不需要在每个更新逻辑里重复写lastModifiedAt: Date.now()。
如果遇到某些特殊场景不需要自动更新lastModifiedAt,可以在更新时手动指定该字段(比如set({ counter: 2, lastModifiedAt: get().lastModifiedAt })),这样中间件就不会覆盖你手动设置的值了。
内容的提问来源于stack exchange,提问作者hendra
相关产品推荐
相关产品推荐

