Search code examples
reactjszustand

Using Persist from Zustand for state management in localStorage


Is it possible to only persist certain states from the Zustand store and not all?

For instance I have the following:

import {create} from "zustand"

export const useAuthStore = create((set, get) => ({
user: null,
isError: false,
isLoading: false,
message; "",
register: async() => {
  //some function
},
getUser: async() => {
  set({ isLoading: true });
try{
  const resp = await fetch(API_URL + "/getuser", {
      method: "GET",
      credentials: "include",
  });

  const userData = await resp.json();
  if (resp.ok) {
                set({ isLoading: false, isSuccess: true, isLoggedIn: true, user: 
   {...userData} });
  };
} catch(error) {
console.log(error);
}
}
//Some other functions below
}))

In this case, what I would like to store in localStorage is the user from my getUser function so I can access the first name (to display it in the nav bar) when refreshing the website.

Is it possible to use persist middleware to accomplish this (as shown here https://blog.openreplay.com/zustand-state-management-for-react/) or rather I need to directly use the localStorage parameter as shown in this blog: https://medium.com/@1992season/manage-states-using-zustand-and-localstorage-7d66ff12cad6 ?

Thanks in advance.


Solution

  • Yes, it is possible to persist only certain states from the Zustand store. Zustand provides a partialize option that allows you to pick some of the state’s fields to be stored in the storage.

    Here are two examples:

    1. Omitting multiple fields:

    export const useBoundStore = create(
          persist(
            (set, get) => ({
              foo: 0,
              bar: 1,
            }),
            {
              partialize: (state) =>
                Object.fromEntries(
                  Object.entries(state).filter(([key]) => !['foo'].includes(key))
                ),
            }
          )
        );

    In this example, the foo field will not be persisted.

    2. Allowing only specific fields:

    export const useBoundStore = create(
      persist(
        (set, get) => ({
          foo: 0,
          bar: 1,
        }), {
          partialize: (state) => ({
            foo: state.foo,
          }),
        }
      )
    );

    In this example, only the foo field will be persisted.