This blog was last modified 543 days before.
Next.js
is using Server Side Generate (SSG) and Server Side Rendering (SSR).
Next.js Server Side pre-rendering
We already know that we can use use client
to mark a component/route to be client side. But based on Next.js Offical Docs, if we are rendering Full Page Load and not Subsequent Navigation, then Next.js will still do some pre-rendering work.
This feature may cause a Next.js Hydration Error in some cases, for example, when working with zustand persist
.
Why Error Occured
Next.js
has a hydration when rendering full page load. Zustand has rehydration when using persist
middleware.
When loading a full page in browser, persist
will try to execute rehydration with data in local storage, which lead to HTML and DOM change.
If persist
rehydration finished before Next.js
hydration, then Next.js will found that the HTML now (which is changed by persist
rehydration operation) is not the same as one pre-rendered on server, so Next.js will throw an error complaining hydration failed.
How to solve
Zustand was also awared of this problem, and gave their solution in Zustand Offical Doc
Basically, we need a new function call useStore()
as a React Hook.
// 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
Using this hook could make sure that the rehydration work of Zustand happened after Next.js hydration, which finally prevent Next.js Hydration Error.
No any code need to be changed of your store, you only need
-
useStore()
function - A slightly different method of using store in your component
You can use useStore()
in your React components like below:
// yourComponent.tsx
import useStore from './useStore'
import { useBearStore } from './stores/useBearStore'
const bears = useStore(useBearStore, (state) => state.bears)
No comment