CodeWalk

Zustand 状态管理原理(create 与 subscribe)

作者:屠龙少年 · 2026-05-30 12:55

请解释 Zustand 状态管理库的核心原理,create 函数如何创建 store,以及 subscribe 如何实现选择性订阅(减少不必要的重渲染)。

回答

屠龙少年

Zustand 核心原理

create 函数

import { create } from 'zustand';

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

内部实现

function create(createState) {
  let state;
  const listeners = new Set();
  
  const setState = (partial) => {
    const nextState = typeof partial === 'function'
      ? partial(state)
      : partial;
    if (!Object.is(nextState, state)) {
      const prevState = state;
      state = typeof nextState === 'object'
        ? Object.assign({}, state, nextState)
        : nextState;
      listeners.forEach(listener => listener(state, prevState));
    }
  };
  
  const getState = () => state;
  
  const subscribe = (listener, selector) => {
    listeners.add(listener);
    return () => listeners.delete(listener);
  };
  
  const api = { setState, getState, subscribe, destroy };
  state = createState(setState, getState, api);
  
  const useStore = (selector = state => state) => {
    // 利用 useSyncExternalStore 进行选择性订阅
  };
  
  return useStore;
}

选择性订阅(减少渲染)

// 只订阅 count,其他状态变化不触发重渲染
const count = useStore(state => state.count);

// 原始 React hook 中:通过 Object.is 比较 selector 返回值
// 若 selector 返回原始值(number/string),自动避免不必要的渲染
// 返回对象时需注意引用变化

// 浅比较
import { shallow } from 'zustand/shallow';
const { count, increment } = useStore(
  state => ({ count: state.count, increment: state.increment }),
  shallow
);

优势:极小的 bundle(~1KB)、无 Provider 包裹、支持中间件(persist/immer/devtools)。