Search code examples
reactjsnext.jsserver-side-renderingnext.js13jotai

Next.js 13 - Jotai's useHydrateAtoms hook causes a UI missmatch


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.

Server component (page)
const getData = async () => {
 // ...
}

export default async function Page() {
  const data = await getData();
  return <ChildComponent initialState={data} />;
}
Client component
"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?


Solution

  • 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.

    How to I fixed the error

    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.