Working on a Next.js 13 project using the new app directory and jotai as global state manager. Now I am trying to pass an initial state to my atoms using the useHydrateAtoms
hook as seen in the official documentation, but this causes a hydration error.
Following is an simplified version of the code that is currently used, it passes the data received from the server side component to a client component that calls useHydrateAtoms
and uses useAtom
to read and write from/to that atom.
const getData = async () => {
// ...
}
export default async function Page() {
const data = await getData();
return <ChildComponent initialState={data} />;
}
"use client";
export function ChildComponent({ initialState }) {
useHydrateAtoms([[myAtom, initialState]]);
const [data, setData] = useAtom(myAtom);
return <>{data.id}</>;
}
When I dynamically import the child component using next/dynamic
with the SSR option set to false or I remove the useHydrateAtoms
hook, the error disappears completely but both of those solutions defy the purpose of this implementation.
How can I provide a initial state to my atom with a value from the server so the atom is not null
upon the first client side render?
I have discovered that the useHydrateAtoms
hook was not the issue per-se, it was a client component accessing the state in a different part of the UI imported dynamically via next/dynamic with the ssr
option set to false
. This caused the value displayed by the component to change on first render, what in return caused a UI mismatch.
Simply move the component that calls useHydrateAtoms
to the top of the component tree, this will ensure that all children will render with the correct value.