主题
来自 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: