Zustand 源码阅读心得

一、引言

  • 背景动机
    为什么选择阅读 Zustand 源码?(轻量、设计思想、性能优化等)
  • 阅读目标
    理解状态管理核心机制、学习设计模式、探究性能优化策略
  • 库简介
    Zustand 的核心定位:轻量级、不可变、基于 Hook 的状态管理

二、核心概念剖析

1. 关键设计思想

  • 单一全局 Store 与多 Store 模式
  • 不可变更新模式(Immer 集成)
  • 细粒度响应式更新(状态切片订阅)
  • 中间件机制(Redux 兼容、持久化、日志等)

2. 核心 API 分析

  • createStore() 的创建流程
  • useStore Hook 的内部依赖追踪
  • create 函数

三、关键源码解析

1. Store(Vanilla Store) 创建过程

// 示例代码片段 + 分析
function createStoreImpl(createState) {
  let state; // 当前状态闭包存储
  const listeners = new Set(); // 订阅者集合

  const setState = (partial, replace) => {
    // 状态合并逻辑...
    // 通知所有订阅者
    listeners.forEach((listener) => listener(state, previousState));
  };

  const getState = () => state;

  const subscribe: StoreApi<TState>['subscribe'] = (listener) => {
    listeners.add(listener);
    // Unsubscribe
    return () => listeners.delete(listener);
  };

  const api = { setState, getState, getInitialState, subscribe };

  return api as any;
}

export const createStore = ((createState) =>
  createState ? createStoreImpl(createState) : createStoreImpl) as CreateStore;

核心就是createStoreImpl这个函数,执行完后到这一步基本就是一个存储状态+支持订阅的对象

2. useStore Hook 依赖追踪

// 示例代码片段 + 分析
// selector为undefined 时默认快照函数返回整个store状态
const identity = <T>(arg: T): T => arg;

export function useStore<TState, StateSlice>(
  api: ReadonlyStoreApi<TState>, // Vanilla Store
  selector: (state: TState) => StateSlice = identity as any,
) {
  // useSyncExternalStore 订阅外部store的hook
  // 接收三个参数
  // 第一个参数:订阅函数,返回一个取消订阅函数
  // 第二个参数:获取快照函数
  // 第三个参数:获取服务器端快照函数(可选)
  // 返回值:根据快照函数返回值
  // 作用:监听store变化,当store变化时,根据快照函数返回值比较确定发生了变化,react就重新渲染组件
  const slice = React.useSyncExternalStore(
    api.subscribe,
    () => selector(api.getState()),
    () => selector(api.getInitialState()),
  );
  return slice;
}

useStore这一函数通过useSyncExternalStore这一hook实现对store的订阅,当store变化时,react就重新渲染组件。
即Vanilla Store通过useStore成了受react控制的状态

3. create 函数

export const create = (<T>(createState: StateCreator<T, [], []> | undefined) =>
  createState ? createImpl(createState) : createImpl) as Create;

const createImpl = <T>(createState: StateCreator<T, [], []>) => {
  const api = createStore(createState); // 本质上也是要先创建Vanilla Store

  const useBoundStore: any = (selector?: any) => useStore(api, selector); // 外部调用useBoundStore === 执行useStore使状态具备响应式

  Object.assign(useBoundStore, api);

  return useBoundStore;
};

因此可以说明:create = createStore + useStore

4. create和createStore选择总结

场景使用的 API说明
React 组件create直接生成 React Hook,开箱即用
非 React 环境createStore创建框架无关的原始 Store
混合使用createStore + useStore在 React 外创建 Store,再手动绑定到组件

💡 最佳实践:

  • 优先用 create 开发 React 应用(更简洁)。

  • 仅当需要脱离 React 操作状态时(如通用库、SSR、全局监听),才用 createStore。