コンテンツにスキップ

HydrateFallback

このコンテンツはまだ日本語訳がありません。

HydrateFallback

HydrateFallback 组件是一种通知 Remix 您不想在 clientLoader 运行 hydration 之前渲染路由组件的方式。导出后,Remix 将在 SSR 期间渲染 fallback 而不是您的默认路由组件,并在 clientLoader 完成后在客户端渲染您的路由组件。

最常见的用例是仅限客户端的路由(例如浏览器内的画布游戏)以及使用客户端数据(例如已保存的用户偏好)扩充服务器数据。

routes/client-only-route.tsx
export async function clientLoader() {
const data = await loadSavedGameOrPrepareNewGame();
return data;
}
// Note clientLoader.hydrate is implied without a server loader
export function HydrateFallback() {
return <p>Loading Game...</p>;
}
export default function Component() {
const data = useLoaderData<typeof clientLoader>();
return <Game data={data} />;
}
routes/augmenting-server-data.tsx
export async function loader() {
const data = getServerData();
return json(data);
}
export async function clientLoader({
request,
params,
serverLoader,
}: ClientLoaderFunctionArgs) {
const [serverData, preferences] = await Promise.all([
serverLoader(),
getUserPreferences(),
]);
return {
...serverData,
preferences,
};
}
clientLoader.hydrate = true;
export function HydrateFallback() {
return <p>Loading user preferences...</p>;
}
export default function Component() {
const data = useLoaderData<typeof clientLoader>();
if (data.preferences.display === "list") {
return <ListView items={data.items} />;
} else {
return <GridView items={data.items} />;
}
}

关于 HydrateFallback 的行为,有几个细微差别值得注意:

  • 它只与初始文档请求和水合有关,不会在任何后续客户端导航中呈现
  • 仅当您在给定路由上设置 clientLoader.hydrate=true 时才相关
  • 如果您有一个没有服务器 loaderclientLoader,它也相关,因为这意味着 clientLoader.hydrate=true,因为否则根本没有加载器数据可以从 useLoaderData 返回
  • 即使您在这种情况下没有指定 HydrateFallback,Remix 也不会呈现您的路由组件,并且会冒泡到任何祖先 HydrateFallback 组件
  • 这是为了确保 useLoaderData 保持快乐路径
  • 如果没有服务器 loaderuseLoaderData 将在任何呈现的路由组件中返回 undefined
  • 您无法在 HydrateFallback 中呈现 <Outlet/>,因为无法保证子路由正常运行,因为它们的祖先加载器数据可能不如果它们在 hydration 上运行 clientLoader 函数,则仍然可用(即,诸如 useRouteLoaderData()useMatches() 之类的用例)

参见: