Next.js 13 – Jotai 的 useHydrateAtoms 钩子导致 UI 不匹配

huangapple go评论79阅读模式
英文:

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

问题

Sure, here's the translated portion of your text:

"在一个使用新的应用程序目录和 jotai 作为全局状态管理器的 Next.js 13 项目上工作。现在我正在尝试使用 useHydrateAtoms 钩子将初始状态传递给我的原子(atom),如官方文档中所示,但这会引发一个水合错误。

以下是当前使用的代码的简化版本,它将从服务器端组件接收到的数据传递给调用 useHydrateAtoms 并使用 useAtom 从/向该原子读取和写入数据的客户端组件。

服务器端组件(页面)
const getData = async () => {
 // ...
}

export default async function Page() {
  const data = await getData();
  return <ChildComponent initialState={data} />;
}
客户端组件
"使用客户端";

export function ChildComponent({ initialState }) {
  useHydrateAtoms([[myAtom, initialState]]);
  const [data, setData] = useAtom(myAtom);
  return <>{data.id}</>;
}

当我使用 next/dynamic 动态导入子组件,并将 SSR 选项设置为 false,或者删除 useHydrateAtoms 钩子时,错误完全消失,但这两种解决方法都不符合这种实现的目的。

如何提供一个来自服务器的初始状态以使原子在首次客户端渲染时不为 null?"

英文:

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?

答案1

得分: 1

我已经发现 useHydrateAtoms 钩子本身并不是问题,问题实际上出在一个客户端组件上,该组件在 UI 的不同部分通过 next/dynamic 动态导入,而且 ssr 选项设置为 false。这导致了组件在首次渲染时显示的值发生变化,从而导致了 UI 不匹配。

如何修复这个错误

只需将调用 useHydrateAtoms 的组件移到组件树的顶部,这将确保所有子组件都使用正确的值进行渲染。

英文:

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.

huangapple
  • 本文由 发表于 2023年6月8日 16:38:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76430039.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定