Zustand's store not persistent

92 views Asked by At

I am trying to create a frontend with zustand to manage the state of my app. But whenever i try to call the signIn method from the userStore it set the token in the store but i doesn't seems to persist when i refresh the page, however i can still find the JWT token in the "Storage" of my browser.

import { createStore } from "zustand/vanilla";
import { APIUser } from "@portail_mem_deport/common";
import { signup, signin } from "@/lib/api/auth";

interface UserStoreState {
  user: APIUser | null;
  token: string | null;
  tokenCreatedAt: number | null;
  setUser: (newUser: APIUser) => void;
  signIn: (username: string, password: string) => Promise<boolean>;
  signUp: (username: string, password: string) => Promise<boolean>;
  signOut: () => void;
  isSignIn: () => boolean;
}

export default createStore<UserStoreState>((set, get) => ({
  user: null,
  token: null,
  tokenCreatedAt: null,

  signIn: async (username, password) => {
    try {
      const resp: any = await signin(username, password);

      console.log("Resp token: ", resp.token);
      if (resp.token) {
        const now = Date.now();
        localStorage.setItem("token", resp.token);
        localStorage.setItem("tokenCreatedAt", `${now}`);
        set({
          token: resp.token,
          tokenCreatedAt: now,
        });
      }
    } catch (error) {
      console.error("Error signing in:", error);
      return false;
    }
    return true;
  },

  isSignIn: () => {
    return get().token !== null;
  },
}));

So is it the expected behaviour and if so how can i manage to keep my store updated ?

When i call the signin function :

const { signIn, token } = userStore.getState();

async function onSubmit(values: z.infer<typeof formSchema>) {
    await signIn(values.username, values.password);
    console.log("Local storage: ", localStorage.get("token"));
    console.log("Token:", token);
}

Output:

Resp token:  eyJhbGciOiJIUz.......65i1Av-c
FormLogin.tsx:30 Form Login Token:   eyJhbGciOiJIUz.......65i1Av-c

I have tried to update my store with the localstorage but it's to "dirty" :(

1

There are 1 answers

0
Yasha_ops On

I finally found how to do it :)

export default createStore<UserStoreState>()(
  persist(
    (set: any, get) => ({
      user: null,
      token: null,
      tokenCreatedAt: null,

      signIn: async (username, password) => {
        try {
          const resp: any = await signin(username, password);

          console.log("Resp token: ", resp.token);
          if (resp.token) {
            const now = Date.now();
            localStorage.setItem("token", resp.token);
            localStorage.setItem("tokenCreatedAt", `${now}`);
            set({
              token: resp.token,
              tokenCreatedAt: now,
            });
          }
        } catch (error) {
          console.error("Error signing in:", error);
          return false;
        }
        return true;
      },
      isSignIn: () => {
        return get().token !== null;
      },
    }),
    {
      name: "user-store", // name for the persist middleware
      getStorage: () => localStorage, // specify where to store the data
    }
  )
);