zustand

github (opens in a new tab)

热门状态管理库之一,和 react 的融合性非常好,react 应用的首选之一,也可以直接使用

工作中深度使用了一下(除了 middleware),真的很爽,非常灵活,TS 支持也非常好

一些最佳实践:

源码深入:

源码的 TS 体操比较多,难懂。核心 store 的代码很简单。

Update: 最新 V5 版本(只支持 React 18,因为 useSyncExternalStore):

  • 直接使用了 useSyncExternalStore 而不在外部依赖他的 polyfill 库

  • export function useStore<TState, StateSlice>(
      api: ReadonlyStoreApi<TState>,
      selector: (state: TState) => StateSlice = identity as any
    ) {
      const slice = React.useSyncExternalStore(
        api.subscribe,
        () => selector(api.getState()),
        () => selector(api.getInitialState())
      );
      React.useDebugValue(slice);
      return slice;
    }
  • 注意在 react 中使用 useStore 的 selector 时候,避免写每次返回新对象的 selector,否则会在 useSyncExternalStore 中出现死循环 render(因为 useSyncExternalStore 里是通过 Object.is 来做 diff 判断的),可以使用 zustand 的 useShallow (opens in a new tab) 做浅比较

    • 可以看到内部实现的比较数组之类可迭代的对象,用的是迭代器属性

      // Ordered iterables
      const compareIterables = (
        valueA: Iterable<unknown>,
        valueB: Iterable<unknown>
      ) => {
        const iteratorA = valueA[Symbol.iterator]();
        const iteratorB = valueB[Symbol.iterator]();
        let nextA = iteratorA.next();
        let nextB = iteratorB.next();
        while (!nextA.done && !nextB.done) {
          if (!Object.is(nextA.value, nextB.value)) {
            return false;
          }
          nextA = iteratorA.next();
          nextB = iteratorB.next();
        }
        return !!nextA.done && !!nextB.done;
      };