next.jszustand

Initing a zustand store with outside data


I'm using a Zustand store to manage state.  I want to fill my store with data from an API; currently, my store has an init() function that does the data fetching and setting. However, this is a bit messy. The store is created with all empty values; init() is called from a component, and then the store is useable.

This requires an isInitialized boolean and checks on the subscribers so they don't trigger before init is done.

I've tried to figure out how I can run init on the creation of the store, but that doesn't seem possible.

And setting the values in createStore directly doesn't work as it can't await the result of the fetches from the api as the create function can't be async.

What is the correct way to initialize a Zustand store with API data?


Solution

  • I ended up figuring out a solution:

    Follow Zustands ReadMe to create a store context provider. This way you can pass props to the createStore function.

    In the provider you can now use an useEffect hook to await your api data and pass it to your createStore function. The provider ends up looking like this:

    const storeRef = useRef<StoreType | null>(null);
    useEffect(() => {
        const fetchData = async () => {
                const fetchedData = await fetchMyData();
          ]);
          
          storeRef.current = createMyStore(fetcheddata);
        };
    
        fetchData();
      }, []);
    
      return (
        <StoreContext.Provider value={storeRef.current}>
          {children}
        </StoreContext.Provider>
      );