2

In my Zustand store I try loading initial state from data persisted in Local storage (I did not opt for middle-ware as there were some kinks with Next that I didn't want to deal with):

const getInitialProject = (): Project => {
    const project = loadCurrentProjectFromLs()

    return (
        project ?? {
            projectName: '',
            cards: [],
        }
    )
}

const useProjectStore = create<ProjectStore>((set, get) => ({
    ...getInitialProject(),
...

However the first render of page is done on server, not on the client (In React and Next.js constructor, I am getting "Reference Error: localstorage is not defined"), which means that the local storage is not accessible at that time.

Which means that my code is not working properly, because the state can only be update after the first render, but the hooks that led to Zustand initialization are fired during the first render.

Is there a better way to tackle that problem than using useEffect hook that would update the store when localStorage becomes accessible? I would love the logic to be a part of the store, not the client, but I am unable to think of anything better than a loop with a timer...

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Faire
  • 706
  • 1
  • 9
  • 31

1 Answers1

1

You can use middleware to have persisted state. Try out Persist and Sync middleware that I created to solve a similar issue.

Install

$ pnpm add persist-and-sync
# or
$ npm install persist-and-sync
# or
$ yarn add persist-and-sync

And just add it to your state creator

import { create } from "zustand";
import { persistNSync } from "persist-and-sync";

type MyStore = {
    count: number;
    set: (n: number) => void;
};

const useStore = create<MyStore>(
    persistNSync(
        set => ({
            count: 0,
            set: n => set({ count: n }),
        }),
        { name: "my-channel" },
    ),
);

⚡Boom! Just a couple of lines and your state perfectly syncs between tabs/windows and it is also persisted using localStorage!

Mayank Kumar Chaudhari
  • 16,027
  • 10
  • 55
  • 122