跳到主要内容

Zustand 状态与订阅

Zustand 怎样组织组件外的共享状态?​

  • Store: 用 create 定义状态与操作,组件通过返回的 Hook 选择片段,同一 store 可供多个组件订阅;
  • 选择边界: 适合确实需要跨组件共享的数据,局部输入或短暂 UI 状态不必全部提升到外部 store;
npm install zustand

如何在 action 中更新当前状态?​

  • Set: 用 set 提交新片段,基于旧值计算时传更新函数;嵌套对象仍需不可变更新;
  • Get: 在 action 执行时读取 store 最新状态,适合需要结合多项现有值的操作,不会修改 React 已有闭包变量;
import { create } from "zustand";

export const useCounter = create((set, get) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
reset: () => set({ count: 0 }),
readCount: () => get().count,
}));

组件怎样只订阅需要的片段?​

  • Selector: 通过选择函数返回需要的值,避免直接订阅整个 store 后让不相关变化触发更新;
  • 相等判断: 选择结果保持相等时,可以避免由该订阅带来的重渲染,但父组件、Context 或本地 state 仍可能使组件重新执行;
function Counter() {
const count = useCounter((state) => state.count);
const increment = useCounter((state) => state.increment);
return <button onClick={increment}>{count}</button>;
}

为什么选择 action 通常不会随数值变化更新?​

  • 函数身份: 创建 store 时定义的 action 通常保持同一引用,数值变化不会改变 selector 结果;
  • 条件限制: 若更新时替换了该函数,订阅结果就变了,不能把“只选 action”当作绝不重渲染的保证;
  • 派生对象: 返回新对象或数组的 selector 需要额外注意引用稳定,见类型与选择器笔记;