1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React Router v7】 Dataモードで部分的にローディングを表示する方法

1
Last updated at Posted at 2026-02-22

はじめに

React RouterのDataモードを使ってみようと思い、loaderで非同期の処理を書いたときに詰まったので投稿します。

環境

React ^19.2.0
React Router ^7.13.0

問題

下記のようにloaderで非同期処理を実行した時に、非同期処理が不要なコンポーネント(ヘッダーなど)も描画されませんでした。
loaderがページコンポーネントの描画前に実行されるため、このような挙動になっています。

PageRouter.tsx
export const PageRoute = () => {
  const router = createBrowserRouter([
    {
      Component: MainLayout,
      children: [
        {
          path: 'templates/:publicId',
          Component: TemplateDetail,
          loader: async ({ params }: LoaderFunctionArgs): {currentPost: Promise<DeclincePost>} => {
            const currentPost = await selectPost(params.publicId ?? '');
          
            return { currentPost };
          },
        }
      ],
    },
  ]);

  return <RouterProvider router={router} />;
};
Detail.tsx
export const TemplateDetail: FC = () => {
  const { currentPost } = useLoaderData<{ currentPost: DeclincePost }>();

  return (
    <MainContainer>
      <h2>タイトル</h2>
      <PostDetail post={currentPost}></PostDetail>
    </MainContainer>
  );
};

解決方法

React RouterのAwaitを利用して解決しました。
loaderでは、Promiseを返すように修正しました。
また、hydrateFallbackElementプロパティを追加しないと、No HydrateFallback element provided to render during initial hydrationWarningエラーが発生します。

PageRouter.tsx
hydrateFallbackElement: <></>
loader: ({ params }: LoaderFunctionArgs): { currentPostPromise: Promise<DeclincePost> } => {
  const currentPostPromise = selectPost(params.publicId ?? '');

  return { currentPostPromise };
},
Detail.tsx
export const TemplateDetail: FC = () => {
  const { currentPostPromise } = useLoaderData<{ currentPostPromise: Promise<DeclincePost> }>();
  
  return (
    <MainContainer>
      <h2>タイトル</h2>
      <Suspense fallback={<Spinner />}>
        <Await resolve={currentPostPromise}>
          {(currentPost) => (
            <PostDetail post={currentPost}></PostDetail>
          )}
        </Await>
      </Suspense>
    </MainContainer>
  );
};

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?