React Router v7 已发布。 查看文档
HydrateFallback

HydrateFallback

HydrateFallback 组件是您通知 Remix 的一种方式,表明您不希望在客户端水合作用(hydration)时运行 clientLoader 之后才渲染路由组件。当导出时,Remix 将在服务器端渲染期间渲染回退组件,而不是您的默认路由组件,并且将在 clientLoader 完成后在客户端渲染您的路由组件。

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

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} />;
}
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 保持 “happy-path”
    • 如果没有服务器 loaderuseLoaderData 将在任何渲染的路由组件中返回 undefined
  • 您不能在 HydrateFallback 中渲染 <Outlet/>,因为如果子路由在水合作用时运行 clientLoader 函数,则无法保证子路由能够正确运行,因为它们的祖先加载器数据可能尚未可用(例如,useRouteLoaderData()useMatches() 等用例)

另请参阅

文档和示例根据 MIT 许可证发布