React Routerがプロジェクト内で探す特別なファイルがいくつかあります。これらのファイルはすべて必須ではありません。
このファイルはオプションです。
設定ファイルは、サーバーサイドレンダリングを使用しているかどうか、特定のディレクトリの場所など、アプリの特定の側面を設定するために使用されます。
import type { Config } from "@react-router/dev/config";
export default {
// Config options...
} satisfies Config;
詳細は、react-router config APIを参照してください。
このファイルは必須です。
ルートルート(app/root.tsx
)は、React Routerアプリケーションで唯一の*必須*ルートです。これは、routes/
ディレクトリ内のすべてのルートの親であり、ルート<html>
ドキュメントのレンダリングを担当するためです。
ルートルートはドキュメントを管理するため、React Routerが提供する少数の「ドキュメントレベル」コンポーネントをレンダリングする適切な場所です。これらのコンポーネントは、ルートルート内で一度だけ使用され、ページを正しくレンダリングするためにReact Routerが把握または構築したすべてが含まれています。
import type { LinksFunction } from "react-router";
import {
Links,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from "react-router";
import "./global-styles.css";
export default function App() {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1"
/>
{/* All `meta` exports on all routes will render here */}
<Meta />
{/* All `link` exports on all routes will render here */}
<Links />
</head>
<body>
{/* Child routes render here */}
<Outlet />
{/* Manages scroll position for client-side transitions */}
{/* If you use a nonce-based content security policy for scripts, you must provide the `nonce` prop. Otherwise, omit the nonce prop as shown here. */}
<ScrollRestoration />
{/* Script tags go here */}
{/* If you use a nonce-based content security policy for scripts, you must provide the `nonce` prop. Otherwise, omit the nonce prop as shown here. */}
<Scripts />
</body>
</html>
);
}
ルートルートは、すべてのルートモジュールエクスポートをサポートしています。
ルートルートは、追加のオプションのLayout
エクスポートもサポートしています。Layout
コンポーネントには2つの目的があります。
HydrateFallback
、およびErrorBoundary
でドキュメントの「アプリシェル」が重複するのを避けます。HydrateFallback
/ ErrorBoundary
を切り替えるときに、Reactがアプリシェル要素を再マウントするのを防ぎます。これは、Reactが<Links>
コンポーネントから<link rel="stylesheet">
タグを削除して再追加する場合にFOUCを引き起こす可能性があります。export function Layout({ children }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1"
/>
<Meta />
<Links />
</head>
<body>
{/* children will be the root Component, ErrorBoundary, or HydrateFallback */}
{children}
<Scripts />
<ScrollRestoration />
</body>
</html>
);
}
export default function App() {
return <Outlet />;
}
export function ErrorBoundary() {}
Layout
コンポーネントのuseLoaderData
に関する注意
useLoaderData
は、正常なパスルートレンダリングを目的としているため、ErrorBoundary
コンポーネントで使用することはできません。また、その型指定には、loader
が正常に実行されて何かを返したという組み込みの仮定があります。この仮定は、ErrorBoundary
では成り立ちません。境界線をトリガーしたスローがloader
であった可能性があるためです。ErrorBoundary
でローダーデータにアクセスするには、ローダーデータがundefined
になる可能性を考慮したuseRouteLoaderData
を使用できます。
Layout
コンポーネントは成功フローとエラーフローの両方で使用されるため、この同じ制限が適用されます。リクエストが成功したかどうかによってLayout
のロジックを分岐する必要がある場合は、useRouteLoaderData("root")
とuseRouteError()
を使用できます。
<Layout>
コンポーネントはErrorBoundary
のレンダリングに使用されるため、レンダリングエラーが発生することなくErrorBoundary
をレンダリングできるように*非常に慎重に*する必要があります。Layout
が境界線をレンダリングしようとして別のエラーをスローした場合、それは使用できなくなり、UIは非常に最小限の組み込みデフォルトErrorBoundary
にフォールバックします。
export function Layout({
children,
}: {
children: React.ReactNode;
}) {
const data = useRouteLoaderData("root");
const error = useRouteError();
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1"
/>
<Meta />
<Links />
<style
dangerouslySetInnerHTML={{
__html: `
:root {
--themeVar: ${
data?.themeVar || defaultThemeVar
}
}
`,
}}
/>
</head>
<body>
{data ? (
<Analytics token={data.analyticsToken} />
) : null}
{children}
<ScrollRestoration />
<Scripts />
</body>
</html>
);
}
このファイルは必須です。
routes.ts
ファイルは、どのURLパターンがどのルートモジュールに一致するかを設定するために使用されます。
import {
type RouteConfig,
route,
} from "@react-router/dev/routes";
export default [
route("some/path", "./some/file.tsx"),
// pattern ^ ^ module file
] satisfies RouteConfig;
詳細は、ルーティングガイドを参照してください。
このファイルはオプションです。
デフォルトでは、React Routerはクライアントでアプリのハイドレーションを自動的に処理します。次の方法でデフォルトのエントリクライアントファイルを表示できます。
react-router reveal
このファイルはブラウザのエントリポイントであり、サーバーエントリモジュールでサーバーによって生成されたマークアップのハイドレーションを担当しますが、ここで他のクライアントサイドコードを初期化することもできます。
import { startTransition, StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";
import { HydratedRouter } from "react-router/dom";
startTransition(() => {
hydrateRoot(
document,
<StrictMode>
<HydratedRouter />
</StrictMode>
);
});
これは、ブラウザで最初に実行されるコードです。クライアント側のライブラリを初期化したり、クライアント専用のプロバイダーを追加したりできます。
このファイルはオプションです。
デフォルトでは、React RouterはHTTPレスポンスの生成を処理します。次の方法でデフォルトのエントリサーバーファイルを表示できます。
react-router reveal
このモジュールのdefault
エクスポートは、HTTPステータス、ヘッダー、HTMLを含むレスポンスを作成できる関数であり、マークアップが生成されてクライアントに送信される方法を完全に制御できます。
このモジュールは、現在のリクエストのcontext
とurl
を使用して、<ServerRouter>
要素を使用して現在のページのマークアップをレンダリングする必要があります。このマークアップは、JavaScriptがクライアントエントリモジュールを使用してブラウザにロードされると、(オプションで)再ハイドレートされます。
handleDataRequest
オプションのhandleDataRequest
関数をエクスポートして、データリクエストのレスポンスを変更できます。これらはHTMLをレンダリングしないリクエストですが、クライアント側のハイドレーションが発生した後、ローダーとアクションデータをブラウザに返します。
export function handleDataRequest(
response: Response,
{
request,
params,
context,
}: LoaderFunctionArgs | ActionFunctionArgs
) {
response.headers.set("X-Custom-Header", "value");
return response;
}
handleError
デフォルトでは、React Routerは発生したサーバーサイドエラーをコンソールに記録します。ロギングをより詳細に制御したい場合、またはこれらのエラーを外部サービスにも報告したい場合は、制御できるオプションのhandleError
関数をエクスポートできます(組み込みのエラーロギングは無効になります)。
export function handleError(
error: unknown,
{
request,
params,
context,
}: LoaderFunctionArgs | ActionFunctionArgs
) {
if (!request.signal.aborted) {
sendErrorToErrorReportingService(error);
console.error(formatErrorForJsonLogging(error));
}
}
React Routerのキャンセルと競合状態の処理により、多くのリクエストが中止される可能性があるため、リクエストが中止されたときのロギングは一般的に避けたいことに注意してください。
renderToPipeableStream
またはrenderToReadableStream
を介してHTMLレスポンスをストリーミングする場合、独自のhandleError
実装は、初期シェルレンダリング中に発生したエラーのみを処理します。後続のストリーミングレンダリング中にレンダリングエラーが発生した場合、React Routerサーバーはその時点で既にレスポンスを送信しているため、これらのエラーを手動で処理する必要があります。
renderToPipeableStream
の場合、これらのエラーはonError
コールバック関数で処理できます。エラーがシェルレンダリングエラー(無視できる)だったのか、非同期だったのかを知るために、onShellReady
でブール値を切り替える必要があります。
例については、Nodeのデフォルトのentry.server.tsx
を参照してください。
スローされたレスポンス
これは、loader
/ action
関数からスローされたResponse
インスタンスを処理しないことに注意してください。このハンドラの目的は、予期しないスローエラーが発生するコードのバグを見つけることです。loader
/ action
でシナリオを検出して401/404/etc. Response
をスローしている場合、それはコードによって処理される予期されたフローです。それらをログに記録したり、外部サービスに送信したりする場合も、レスポンスをスローするときに行う必要があります。