提问人:mTv 提问时间:11/17/2023 更新时间:11/17/2023 访问量:15
我应该如何处理这个水化错误?
How should I handle this hydration error?
问:
我有一个“使用客户端”组件,它会抛出冻结错误:
2 倍Hydration failed because the initial UI does not match what was rendered on the server.
1 倍There was an error while hydrating this Suspense boundary. Switched to client rendering.
这是组件:
export default function NavigationButton(props: NavigationButtonProps) {
const isInDesktopClient = useDesktopClient((state) => state.isInDesktopClient);
return isInDesktopClient ? (
<Button
{...props}
variant={props.variant}
onClick={() => {
desktopClientPlugin.openInWorkspace(
`${window.location.origin}/${props.href}`,
props.title || "",
props.subTitle,
);
}}
>
{props.children}
</Button>
) : (
<Button
{...props}
component={Link}
href={props.href}
variant={props.variant}
>
{props.children}
</Button>
);
}
它应该呈现一个按钮,如果您在常规浏览器中,该按钮会将您导航到新 URL。但是,如果您在桌面客户端的嵌入式浏览器中,它应该呈现一个按钮,该按钮在桌面客户端的新“工作区”中打开所述 URL。
在应用程序头部加载的组件中设置的 zustand-state,如下所示:isInDesktopClient
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<head>
<ColorSchemeScript />
<DesktopClient />
</head>
<body className={`${circularFont.className} bg-neutral-20`}>
<TRPCProvider>
<MantineProviders>{children}</MantineProviders>
</TRPCProvider>
</body>
</html>
);
}
这是组件,它等待desktopPlugin(允许嵌入式浏览器和桌面客户端通信)的设置。如果它响应,它会将票证存储在 cookie 中,并将 zustand-state 设置为 true 以供以后使用:DesktopClient
export default function DesktopClient() {
useEffect(() => {
const fetchClientTicket = () => {
const interval = setInterval(() => {
if (desktopClientPlugin.isReady()) {
clearInterval(interval);
const clientTicket = desktopClientPlugin.getTicket();
Cookies.set("clientTicket ", clientTicket || "");
useDesktopClient.setState({ isInDesktopClient: true });
}
}, 100);
return () => clearInterval(interval);
};
fetchClientTicket();
}, []);
return null;
}
“isInDesktopClient”显然在服务器上永远不会为真,因此服务器呈现的 html 永远不会与桌面客户端中嵌入式浏览器中的内容匹配。
我怎样才能以一种不会导致补水错误的方式做到这一点?
答: 暂无答案
评论