Skip to content

来自 zustand/context 的 createContext

¥createContext from zustand/context

自 v3.5 以来提供了特殊的 createContext,可避免误用 store 钩子。

¥A special createContext is provided since v3.5, which avoids misusing the store hook.

注意:此功能在 v4 中已弃用,并将在 v5 中删除。参见 迁移

¥Note: This function is deprecated in v4 and will be removed in v5. See Migration.

jsx
import create from 'zustand'
import createContext from 'zustand/context'

const { Provider, useStore } = createContext()

const createStore = () => create(...)

const App = () => (
  <Provider createStore={createStore}>
    ...
  </Provider>
)

const Component = () => {
  const state = useStore()
  const slice = useStore(selector)
  ...

实际组件中的 createContext 使用

¥createContext usage in real components

jsx
import create from "zustand";
import createContext from "zustand/context";

// Best practice: You can move the below createContext() and createStore to a separate file(store.js) and import the Provider, useStore here/wherever you need.

const { Provider, useStore } = createContext();

const createStore = () =>
  create((set) => ({
    bears: 0,
    increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
    removeAllBears: () => set({ bears: 0 })
  }));

const Button = () => {
  return (
      {/** store() - This will create a store for each time using the Button component instead of using one store for all components **/}
    <Provider createStore={createStore}>
      <ButtonChild />
    </Provider>
  );
};

const ButtonChild = () => {
  const state = useStore();
  return (
    <div>
      {state.bears}
      <button
        onClick={() => {
          state.increasePopulation();
        }}
      >
        +
      </button>
    </div>
  );
};

export default function App() {
  return (
    <div className="App">
      <Button />
      <Button />
    </div>
  );
}

使用 props 初始化的 createContext 使用

¥createContext usage with initialization from props

tsx
import create from 'zustand'
import createContext from 'zustand/context'

const { Provider, useStore } = createContext()

export default function App({ initialBears }) {
  return (
    <Provider
      createStore={() =>
        create((set) => ({
          bears: initialBears,
          increase: () => set((state) => ({ bears: state.bears + 1 })),
        }))
      }
    >
      <Button />
    </Provider>
  )
}

迁移

¥Migration

讨论:https://github.com/pmndrs/zustand/discussions/1276

¥Discussion: https://github.com/pmndrs/zustand/discussions/1276

这是使用 v4 API 的新上下文用法。

¥Here's the new context usage with v4 API.

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

const StoreContext = createContext(null)

const StoreProvider = ({ children }) => {
  const storeRef = useRef()
  if (!storeRef.current) {
    storeRef.current = createStore((set) => ({
      // ...
    }))
  }
  return (
    <StoreContext.Provider value={storeRef.current}>
      {children}
    </StoreContext.Provider>
  )
}

const useStoreInContext = (selector) => {
  const store = useContext(StoreContext)
  if (!store) {
    throw new Error('Missing StoreProvider')
  }
  return useStore(store, selector)
}

或者联系一些提供 Zustand v3 类 API 的第三方库:

¥Or reach out to some third-party libraries that provide Zustand v3-like APIs:

Zustand v5.0 中文网 - 粤ICP备13048890号