zustand源码解读-闭包

136 阅读1分钟

🧠 核心思想

Zustand 的目标是:

  • 像 Redux 一样可组合状态
  • 像 React Context 一样方便订阅
  • 比 Context 更 细粒度,只有用到的组件才更新

✅ 总结一句话

Zustand 用闭包封装 store,用 useSyncExternalStore 连接组件,实现了轻量、精准、高性能的状态管理。

🧠 关键机制解析

1. 中心状态容器(store)

Zustand 的状态不是依赖 React 的 useStateuseReducer,而是放在一个纯 JavaScript 对象中(通常叫 store),状态通过闭包私有化管理。

  • 这个 store 包含:
    • 当前的 state
    • 修改状态的 setState 函数
    • 订阅者列表(Set)
    • subscribe 方法用于监听状态变化
const store = {
  state,
  setState(fn),
  getState(),
  subscribe(listener),
}

2. useSyncExternalStore 的作用

React 官方提供的 useSyncExternalStore 是为了让状态管理库可以安全同步地读取外部状态

Zustand 中的 useStore 实际上是一个对 useSyncExternalStoreWithSelector 的封装:

useSyncExternalStore(
  store.subscribe,     // 订阅状态变更
  store.getState,      // 读取当前状态(浏览器)
  store.getState       // 用于 SSR fallback
)

📌 它的作用就是把一个 React 之外的“状态源”连接到组件中,只要状态变了,就触发重新渲染。


3. 精细更新(Selector)

Zustand 支持传入 selector(选择器函数),只取出组件用到的部分状态,并结合 Object.is 比较,避免无意义的渲染。

const bears = useBearStore(state => state.bears);

组件只会在 bears 变动时才重新渲染,其他状态的变化不会影响它。


🔁 总流程总结

  1. 你通过 create() 创建 store 并返回一个 useStore hook。
  2. 组件调用 useStore(selector) 从 store 中读取状态。
  3. Zustand 用 useSyncExternalStore 来订阅状态变动,并自动触发组件更新。
  4. 当你通过 setState() 改变状态时,会触发所有订阅者的回调,组件就更新了。