-
I notice that https://github.com/pmndrs/zustand/blob/main/docs/previous-versions/zustand-v3-create-context.md says:
I think this createContext is more usable that react's createContext. Please don't deprecated or remove it in the further version. Reason why this createContext is more usableths most useful situation is refactor a app to a component. Here's progress: At first I create a App without context : // store.ts
import create from "zustand";
export const useStore = create((set) => ({
bears: 0,
increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
removeAllBears: () => set({ bears: 0 })
})); compoents use // Component.ts
import {useStore} from './store'
const ButtonChild = () => {
const state = useStore();
return (
<div>
{state.bears}
<button
onClick={() => {
state.increasePopulation();
}}
>
+
</button>
</div>
);
};
export default ButtonChild But oneday, I need to convert this app to a component(like react-flow) to reuse in another app. with zustand createContext, what I need to do is just wrapper the App with a zustand's createContext, and don't need to refactor any code in children components. It become a component, can be used in any other app. // store.ts
import create from "zustand";
+ const createStore = ()=> create((set) => ({
- export const useStore = create((set) => ({
bears: 0,
increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
removeAllBears: () => set({ bears: 0 })
}));
+ const { Provider, useStore } = createContext();
+ export { Provider, useStore , createStore } // Wrapper.tsx
import {Provider, createStore } from './store'
const Wrapper =()=>{
return (
<Provider createStore={createStore}>
<ButtonChild />
</Provider>
);
} But what if use it with react's context?
Compare to zustand 's context usage, It's real bad. So please keep the zustand's createContext usage in the furture. And it's a more recommended method in my mind. |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 31 replies
-
The point is you can create v3 compatible createContext with v4 new APIs. Your feedback is important and I agree that there are some use cases. I wonder if anyone would be interested in creating a 3rd-party package, if it's valuable. |
Beta Was this translation helpful? Give feedback.
-
I just released a library with v3.5 context : https://github.com/arvinxx/zustand-utils. Maybe I can handle with some migration documents context releated. @dai-shi |
Beta Was this translation helpful? Give feedback.
-
I fail to understand how moving to react context as in the migration guide allows us to have multiple instances of the same store, with some state passed from a parent component, as before, because these examples are creating the store at the module level. If we create a store instance at the module level (singleton) we can't have more than one instance of the same store for different components / component instances. TypeScript also says |
Beta Was this translation helpful? Give feedback.
-
Perhaps I should've kept a bit more code for context - I was using Indeed, now that I review a bit more of the docs, I see https://docs.pmnd.rs/zustand/guides/practice-with-no-store-actions
... but it seems to offer something of a downside when it comes to adapting it to the context API. I could maybe benefit from re-reading some of this discussion, as well as reviewing the utility libraries mentioned... heading out now, but FWIW here is a code sandbox with a simple store (and lots of boilerplate for types etc). I keep a import { createContext, useContext, useEffect, useRef } from "react";
import { createStore } from "zustand";
import { useStoreWithEqualityFn } from "zustand/traditional";
const StoreContext = createContext(null);
const stores = new Map();
export const StoreProvider = ({ children, id }) => {
const storeRef = useRef();
if (!storeRef.current) {
console.log("init store", id);
storeRef.current = createStore(() => ({
count: 0,
}));
}
useEffect(() => {
if (storeRef.current) stores.set(id, storeRef.current);
return () => {
stores.delete(id);
};
}, [storeRef.current, id]);
return (
<StoreKeyContext.Provider value={id}>
<StoreContext.Provider value={storeRef.current}>
{children}
</StoreContext.Provider>
</StoreKeyContext.Provider>
);
};
export function useStoreInContext(selector) {
const store = useContext(StoreContext);
if (!store) {
throw new Error("Missing StoreProvider");
}
//@deprecated...
//return useStore(store, selector);
return useStoreWithEqualityFn(store, selector);
}
/**
* const storeGetter = useStoreGetter()
* useEffect(() => {
* storeGetter().setState(...)
* })
*/
export function useStoreGetter() {
const k = useContext(StoreKeyContext);
return () => stores.get(k);
} Any thoughts welcomed (including on the type stuff, which it may be possible to make a bit less involved on the provider side with some thought...) |
Beta Was this translation helpful? Give feedback.
-
It might be better if you include the code as text rather than an image. I'm not actively using Immer at the moment and don't have any immediate thoughts on whether there are problems with your approach, but may review at some point. |
Beta Was this translation helpful? Give feedback.
The point is you can create v3 compatible createContext with v4 new APIs.
We want to make the library minimalistic, and thus considering deprecation.
Your feedback is important and I agree that there are some use cases. I wonder if anyone would be interested in creating a 3rd-party package, if it's valuable.