Zuzstand docs, integrating persisting data with Next js: https://docs.pmnd.rs/zustand/integrations/persisting-store-data#usage-in-next.js
NextJS uses Server Side Rendering, and it will compare the rendered component on the server with the one rendered on the client. But since you are using data from the browser to change your component, the two renders will differ and Next will throw a warning at you.
The errors usually are:
- Text content does not match server-rendered HTML
- Hydration failed because the initial UI does not match what was rendered on the server
- There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering
To solve these errors.
create a custom hook so that Zustand waits for a little before changing your components.
Create a file with the following:
// useStore.ts
import { useState, useEffect } from 'react'
const useStore = <T, F>(
store: (callback: (state: T) => unknown) => unknown,
callback: (state: T) => F
) => {
const result = store(callback) as F
const [data, setData] = useState<F>()
useEffect(() => {
setData(result)
}, [result])
return data
}
export default useStore
Now in your pages, you will use the hook a little bit differently:
// useBearStore.ts
import { create } from 'zustand'
import { persist } from 'zustand/middleware'
// the store itself does not need any change
export const useBearStore = create(
persist(
(set, get) => ({
bears: 0,
addABear: () => set({ bears: get().bears + 1 }),
}),
{
name: 'food-storage',
}
)
)
// yourComponent.tsx
import useStore from './useStore'
import { useBearStore } from './stores/useBearStore'
const bears = useStore(useBearStore, (state) => state.bears)