336 文字
2 分

React Router V6でOutletを利用したページコンテンツの遅延読み込み

ページコンポーネントを雑に遅延読み込みさせていると、各ページの初回読み込み時にチラツキが発生してしまう場合がある。

また Suspense を利用して Loading 状態を作るにしても、レイアウトを構成するヘッダーなども一緒に含まれてしまうと、ユーザーはアプリが壊れたような印象を受けてしまう。

そこで、React Router v6 の Outlet を利用して、ページのコンテンツのみが遅延読み込みされるように、ページのコンテンツとレイアウトを分離して次のようなコードを書いた。

const listPagePreloading = import("../pages/list");
const ListPage = React.lazy(() => listPagePreloading);
const itemPagePreloading = import("../pages/items");
const ItemPage = React.lazy(() => itemPagePreloading);
const editItemPagePreloading = import("../pages/items/edit");
const EditItemPage = React.lazy(() => editItemPagePreloading);
const protectedRoutes: RouteObject[] = [
{
path: "/",
element: <RequireAuth><Outlet /></RequireAuth>,
children: [
{
index: true,
element: <Navigate to="/list" replace />
},
{
path: "/list",
element: <ListPageLayout />
children: [
{
index: true,
element: <ListPage />
}
]
},
{
path: "/items/:itemId",
element: <ItemPageLayout />,
children: [
{
index: true,
element: <ItemPage />
},
{
path: "/edit",
element: <EditItemPage />
}
]
}
]
}
]

ディレクトリ構造は次のようにして、レイアウトとページコンテンツはファイルを分離している。

- pages/
- list/
- layout.tsx
- index.tsx
- items/
- index.tsx
- layout.tsx
- edit/
- index.tsx
...

RequireAuth の実装は次のようになっている。

const RequireAuth = ({ children }: { children: JSX.Element }) => {
const auth = useAuth();
const location = useLocation();
if (!auth.authenticated) {
return <Navigate to="/login" state={{ from: location }} replace />;
}
return children;
};
React Router V6でOutletを利用したページコンテンツの遅延読み込み
https://blog.ohirunewani.com/posts/react-router-v6-outlet/
作者
hrdtbs
公開日
2022-01-22
ライセンス
CC BY-NC-SA 4.0