跳转到内容

clientLoader

clientLoader

除了(或代替)你的 loader,你还可以定义一个将在客户端上执行的 clientLoader 函数。

每个路由可以定义一个 clientLoader 函数,在渲染时向路由提供数据:

export const clientLoader = async ({
request,
params,
serverLoader,
}: ClientLoaderFunctionArgs) => {
// call the server loader
const serverData = await serverLoader();
// And/or fetch data on the client
const data = getDataFromClient();
// Return the data to expose through useLoaderData()
return data;
};

此功能仅在客户端上运行,并且可以通过以下几种方式使用:

  • 代替服务器加载器进行全客户端路由
  • 通过在突变时使缓存无效来与 clientLoader 缓存一起使用
  • 维护客户端缓存以跳过对服务器的调用
  • 绕过 Remix BFF 跳跃并直接从客户端访问您的 API
  • 进一步增强从服务器加载的数据
  • 即从 localStorage 加载用户特定的首选项
  • 促进从 React Router 迁移

水合行为

默认情况下,在初始 SSR 文档请求中,clientLoader 不会在 Remix 应用水合期间为路由执行。这是针对主要(和更简单)用例,其中 clientLoader 不会更改服务器 loader 数据的形状,而只是对后续客户端导航(从缓存中读取或直接命中 API)的优化。

export async function loader() {
// During SSR, we talk to the DB directly
const data = getServerDataFromDb();
return json(data);
}
export async function clientLoader() {
// During client-side navigations, we hit our exposed API endpoints directly
const data = await fetchDataFromApi();
return data;
}
export default function Component() {
const data = useLoaderData<typeof loader>();
return <>...</>;
}

clientLoader.hydrate

如果您需要在初始文档请求的水合过程中运行 clientLoader,则可以通过设置 clientLoader.hydrate=true 来选择加入。这将告诉 Remix 它需要在水合过程中运行 clientLoader。如果没有 HydrateFallback,您的路由组件将使用服务器加载器数据进行 SSR - 然后 clientLoader 将运行,并且返回的数据将在水合路由组件中就地更新。

如果路由导出 clientLoader 而未导出服务器 loader,则 clientLoader.hydrate 会自动被视为 true,因为没有服务器数据可以用于 SSR。因此,我们始终需要在渲染路由组件之前在 hydration 上运行 clientLoader

HydrateFallback

如果您需要避免在 SSR 期间渲染默认路由组件,因为您有必须来自 clientLoader 的数据,则可以从将在 SSR 期间渲染的路由中导出 HydrateFallback 组件,并且只有当 clientLoader 在 hydration 上运行时,您的路由器组件才会被渲染。

参数

params

此函数接收与 loader 相同的 params 参数。

request

此函数接收与 loader 相同的 request 参数。

serverLoader

serverLoader 是一个异步函数,用于从服务器 loader 获取此路由的数据。在客户端导航中,这将对 Remix 服务器 loader 进行 fetch 调用。如果您选择在 hydration 上运行 clientLoader,则此函数将返回已在服务器上加载的数据(通过 Promise.resolve)。

参见: