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;
};
此函数仅在客户端运行,并且可以以多种方式使用。
loader
的替代方法。clientLoader
缓存一起使用,通过在更改时使缓存失效来使用。localStorage
加载用户特定偏好。默认情况下,clientLoader
**不会** 在对初始 SSR 文档请求进行 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
,您的路由组件将使用服务器 loader
数据进行 SSR - 然后 clientLoader
将运行,返回的数据将在水合路由组件中就地更新。
clientLoader
而不导出服务器 loader
,那么 clientLoader.hydrate
将自动被视为 true
,因为没有服务器数据可以进行 SSR。因此,我们始终需要在水合期间运行 clientLoader
才能渲染路由组件。
如果您需要避免在 SSR 期间渲染默认路由组件,因为您有来自 clientLoader
的必需数据,您可以从您的路由导出一个 HydrateFallback
组件,该组件将在 SSR 期间渲染,并且只有在 clientLoader
在水合期间运行后,您的路由器组件才会渲染。
params
request
serverLoader
serverLoader
是一个异步函数,用于从该路由的服务器 loader
获取数据。在客户端导航时,它将使用 fetch 调用 Remix 服务器 loader
。如果您选择在水合时运行您的 clientLoader
,则此函数将返回您在服务器上已经加载的数据(通过 Promise.resolve
)。
另请参阅