データは、loader
とclientLoader
からルートコンポーネントに提供されます。
ローダーデータは、ローダーから自動的にシリアライズされ、コンポーネントでデシリアライズされます。文字列や数値のようなプリミティブ値に加えて、ローダーはPromise、Map、Set、日付などを返すことができます。
clientLoader
は、クライアントでデータをフェッチするために使用されます。これは、ブラウザからのみデータをフェッチしたいページやプロジェクト全体で役立ちます。
// route("products/:pid", "./product.tsx");
import type { Route } from "./+types/product";
export async function clientLoader({
params,
}: Route.ClientLoaderArgs) {
const res = await fetch(`/api/products/${params.pid}`);
const product = await res.json();
return product;
}
export default function Product({
loaderData,
}: Route.ComponentProps) {
const { name, description } = loaderData;
return (
<div>
<h1>{name}</h1>
<p>{description}</p>
</div>
);
}
サーバーレンダリングの場合、loader
は初期ページロードとクライアントナビゲーションの両方に使用されます。クライアントナビゲーションは、React Routerによるブラウザからサーバーへの自動的なfetch
を通じてローダーを呼び出します。
// route("products/:pid", "./product.tsx");
import type { Route } from "./+types/product";
import { fakeDb } from "../db";
export async function loader({ params }: Route.LoaderArgs) {
const product = await fakeDb.getProduct(params.pid);
return product;
}
export default function Product({
loaderData,
}: Route.ComponentProps) {
const { name, description } = loaderData;
return (
<div>
<h1>{name}</h1>
<p>{description}</p>
</div>
);
}
loader
関数はクライアントバンドルから削除されるため、ブラウザに含めることを心配せずにサーバーのみのAPIを使用できることに注意してください。
プリレンダリング時、ローダーはプロダクションビルド中にデータをフェッチするために使用されます。
// route("products/:pid", "./product.tsx");
import type { Route } from "./+types/product";
export async function loader({ params }: Route.LoaderArgs) {
let product = await getProductFromCSVFile(params.pid);
return product;
}
export default function Product({
loaderData,
}: Route.ComponentProps) {
const { name, description } = loaderData;
return (
<div>
<h1>{name}</h1>
<p>{description}</p>
</div>
);
}
プリレンダリングするURLはreact-router.config.tsで指定します。
import type { Config } from "@react-router/dev/config";
export default {
async prerender() {
let products = await readProductsFromCSVFile();
return products.map(
(product) => `/products/${product.id}`
);
},
} satisfies Config;
サーバーレンダリング時には、プリレンダリングされていないURLは通常どおりサーバーレンダリングされます。これにより、残りをサーバーレンダリングしながら、単一のルートで一部のデータをプリレンダリングできます。
loader
とclientLoader
は一緒に使用できます。loader
は初期SSR(またはプリレンダリング)のためにサーバーで使用され、clientLoader
は後続のクライアントサイドナビゲーションで使用されます。
// route("products/:pid", "./product.tsx");
import type { Route } from "./+types/product";
import { fakeDb } from "../db";
export async function loader({ params }: Route.LoaderArgs) {
return fakeDb.getProduct(params.pid);
}
export async function clientLoader({
params,
}: Route.ClientLoader) {
const res = await fetch(`/api/products/${params.pid}`);
return res.json();
}
export default function Product({
loaderData,
}: Route.ComponentProps) {
const { name, description } = loaderData;
return (
<div>
<h1>{name}</h1>
<p>{description}</p>
</div>
);
}
次へ: アクション
関連情報