Nextjs and Zustand (outside react component)
Unanswered
Silky ant posted this in #help-forum
Silky antOP
Hi, can I use a Zustand store Hi, how can I use a Zustand store outside of a React component in Next.js 15? I can't find any examples in the documentation.
export type ExampleStoreProps = {
enableDevtools?: boolean;
initState: ExampleStoreState;
};
export type ExampleStoreApi = t_StoreApi<ExampleStore, boolean>;
export const createExampleStore = ({
enableDevtools = false,
initState: _initState,
}: ExampleStoreProps) => {
const initState = _initState;
const stateCreator = (set: any, get, store): ExampleStore => ({
...(initState as any),
setExampleProp: (path: string[], value: any) => {
return set((state: ExampleStoreState) =>
produce(state, (draft) => {
_.set(draft.example._config, path, {
...(_.get(draft.example._config, path) || {}),
...value,
});
})
);
},
getExampleProp: (path: string[]) => {
const state = get();
return _.get(state.example._config, path);
},
});
let res = null as any;
if (enableDevtools) {
res = createStore(devtools(stateCreator, { name: "ExampleStore", enabled: enableDevtools }));
} else {
res = createStore(stateCreator);
}
return res as ExampleStoreApi;
};
6 Replies
Silky antOP
export const ExampleContext = createContext<ExampleContextProps | null>(null);
export type ExampleProviderProps = Pick<ExampleStoreProps, "initState">;
export const ExampleProvider = ({
children,
initState,
}: PropsWithChildren & ExampleProviderProps) => {
const enableDevtools = false as const;
const exampleStoreRef = useRef<ExampleStoreApi | null>(null);
if (!exampleStoreRef.current) {
exampleStoreRef.current = createExampleStore({ enableDevtools, initState });
}
return (
<ExampleContext.Provider value={exampleStoreRef.current}>
{children}
</ExampleContext.Provider>
);
};
export const useExampleContext = <T,>(
selector: (state: ExampleStore) => T
): T => {
const store = useContext(ExampleContext) as ExampleStoreApi | null;
if (!store) {
console.error("ExampleContext is missing. Ensure you are within an ExampleProvider.");
throw new Error("useExampleContext must be used within an ExampleProvider");
}
return useStore(store, selector);
};
Roseate Spoonbill
Yes, you can. Stores have two ways of being created - with
Both expose store-related functionality, including
createStore
(without react utils attached) and create
which is both react hook and the actual store. Both expose store-related functionality, including
getState()
method which you can call wherever to access the store and it's data and functions.Take a look at https://zustand.docs.pmnd.rs/apis/create-store#updating-state-based-on-previous-state - there are examples of how the store can be used from inside
addEventListener
callback, without react context at all.@Roseate Spoonbill Yes, you can. Stores have two ways of being created - with `createStore` (without react utils attached) and `create` which is both react hook and the actual store.
Both expose store-related functionality, including `getState()` method which you can call wherever to access the store and it's data and functions.
Silky antOP
Thank you very much for your response ,
I would like to keep this approach but make it accessible in a way other than through the provider. So I did this:
And later I use
I don't know if it's correct — I haven't tested it, but I find it a bit weird
I would like to keep this approach but make it accessible in a way other than through the provider. So I did this:
if (!exampleStoreRef.current) {
const store = createExampleStore({ enableDevtools, initState });
exampleStoreRef.current = store;
externalExampleStoreInstance = store;
}
And later I use
const { ... } = externalExampleStoreInstance.getState()
inside a function that's outside of React components.I don't know if it's correct — I haven't tested it, but I find it a bit weird
Roseate Spoonbill
I've seen people assigning stores to ref whenever the store is not supposed to be global. If your state store can be or is global, you don't need ref at all. You can create store and export it directly outside of react component.
IMHO you need ref or context for sharing store only if your store is localized and can have multiple instances going at the same time