Next.js Discord

Discord Forum

Nextjs and Zustand (outside react component)

Unanswered
Silky ant posted this in #help-forum
Open in Discord
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;
};

1 Reply

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);
};