在 React 中使用 Context 创建 Zustand Store 实例

默认情况下,Zustand 创建的每个 store 都是单例的,也就是说整个应用里只有一个实例。

import { create } from "zustand";

interface BearState {
  bears: number;
  increase: (by: number) => void;
}

const useBearStore = create<BearState>()((set) => ({
  bears: 0,
  increase: (by) => set((state) => ({ bears: state.bears + by })),
}));

有些情况下需要创建多个实例,可以使用 React Context 配合 Zustand,这样每个 Provider 下的组件都能访问到独立的 store 实例。

import { createContext, useContext } from 'react';
import { createStore, useStore } from 'zustand';

interface BearState {
  bears: number;
  increase: (by: number) => void;
}

const BearStoreContext = createContext(null);

// 创建 Provider 组件
export const BearStoreProvider = ({ children, initialState }) => {
  const store = createStore<BearState>()((set) => ({
    bears: 0,
    increase: (by) => set((state) => ({ bears: state.bears + by })),
  }));

  return <BearStoreContext.Provider value={store}>{children}</BearStoreContext.Provider>;
};

// 创建自定义 hook 访问 store
export const useBearStore = <T,>(selector: (state: BearState) => T): T => {
  const store = useContext(BearStoreContext);
  if (!store) {
    throw new Error('Missing BearStoreProvider');
  }
  return useStore(store, selector);
};

使用方式:


function App() {
  return (
    <>
      <BearStoreProvider initialState={{ bears: 1 }}>
        <ComponentA />
      </BearStoreProvider>

      <BearStoreProvider initialState={{ bears: 2 }}>
        <ComponentB />
      </BearStoreProvider>
    </>
  );
}

function ComponentA() {
  const bears = useBearStore((state) => state.bears);
  const increase = useBearStore((state) => state.increase);

  return <>bears: {bears}</>;
}

function ComponentB() {
  const bears = useBearStore((state) => state.bears);
  const increase = useBearStore((state) => state.increase);

  return <>bears: {bears}</>;
}
posted @ 2024-12-05 16:55  nptr  阅读(74)  评论(0)    收藏  举报