0Pricing
React Academy · レッスン

LoadersとActions(Data Router API)

loaderでrender前にルートデータを取得し、actionでフォーム送信を処理します。

「LoadersとActions(Data Router API)」はCoddyKit上の無料React Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。

ローダーとは

React Router v6.4 以降の Data Router では、ローダーはルートに設定する非同期関数です。ルートのレンダリング前にデータを取得し、useEffect で取得するパターンに置き換わります。

ローダーの定義

ルートオブジェクトに loader プロパティを追加します。{ params, request } を受け取り、データ(または Response)を返します。

import { createBrowserRouter } from 'react-router-dom';

async function userLoader({ params }) {
  const res = await fetch(`/api/users/${params.id}`);
  if (!res.ok) throw new Response('Not Found', { status: 404 });
  return res.json();
}

const router = createBrowserRouter([
  { path: '/users/:id', element: <UserDetail />, loader: userLoader },
]);

useLoaderData によるローダーデータの読み取り

useLoaderData() は、ローダーが返した値をそのまま返します。コンポーネントはローダーの処理が完了してからレンダリングされます。

import { useLoaderData } from 'react-router-dom';

function UserDetail() {
  const user = useLoaderData();
  return <h1>{user.name}</h1>;
}

アクションとは

アクションは、データの変更(フォーム送信や削除など)を処理する非同期関数です。フォームの POST 後、ルートが再レンダリングされる前に実行されます。

async function createUserAction({ request }) {
  const formData = await request.formData();
  const name = formData.get('name');
  await fetch('/api/users', {
    method: 'POST',
    body: JSON.stringify({ name }),
    headers: { 'Content-Type': 'application/json' },
  });
  return redirect('/users');
}

Form によるアクションの実行

<form> を React Router の <Form> に置き換えます。送信すると、フィールドが FormData としてシリアライズされ、ルートのアクションが呼び出されます。

import { Form } from 'react-router-dom';

function NewUser() {
  return (
    <Form method="post">
      <input name="name" />
      <button type="submit">Create</button>
    </Form>
  );
}

アクションからのデータの返却

アクションはリダイレクトだけでなく、データも返せます。コンポーネントでは useActionData() で読み取ります。バリデーションエラーを返す場合に便利です。

async function loginAction({ request }) {
  const data = await request.formData();
  const errors = validate(data);
  if (errors) return errors; // returned to useActionData
  await login(data);
  return redirect('/dashboard');
}

function Login() {
  const errors = useActionData();
  return (
    <Form method="post">
      {errors?.email && <p>{errors.email}</p>}
      <input name="email" />
    </Form>
  );
}

useNavigation による読み込み状態

useNavigation() を使うと、ローダーまたはアクションの処理中かどうかを確認できます。これにより、スピナーを表示したり送信ボタンを無効にしたりできます。

function SubmitButton() {
  const navigation = useNavigation();
  const isSubmitting = navigation.state === 'submitting';
  return (
    <button type="submit" disabled={isSubmitting}>
      {isSubmitting ? 'Saving...' : 'Save'}
    </button>
  );
}

defer() による遅延データ

defer() を使うと、ローダーから時間のかかるデータの Promise を返してもレンダリングをブロックせずに済みます。その後、<Await> と Suspense で値を取り出します。

import { defer, Await } from 'react-router-dom';

async function slowLoader() {
  return defer({ fast: await getFast(), slow: getSlow() });
}

function Page() {
  const { fast, slow } = useLoaderData();
  return (
    <>
      <h1>{fast.title}</h1>
      <Suspense fallback={<p>Loading...</p>}>
        <Await resolve={slow}>{data => <Chart data={data} />}</Await>
      </Suspense>
    </>
  );
}

アクション後の再検証

アクションが完了すると、React Router はアクティブなすべてのローダーを自動的に再実行してデータを更新します。手動で再フェッチする必要はありません。

ローダーでのエラー処理

ローダーから Response または任意のエラーを throw します。React Router がそれを捕捉し、ルートの errorElement をレンダリングします。エラーは useRouteError() から取得できます。

function ErrorPage() {
  const error = useRouteError();
  return (
    <div>
      <h1>{error.status} {error.statusText}</h1>
    </div>
  );
}

ナビゲーションを伴わない変更のための Fetcher

useFetcher() を使うと、ナビゲーションせずにローダーやアクションを呼び出せます。ページを離れずに投稿へ「いいね」を付けるインラインフォームなどに便利です。

function LikeButton({ postId }) {
  const fetcher = useFetcher();
  return (
    <fetcher.Form method="post" action={`/posts/${postId}/like`}>
      <button type="submit">Like</button>
    </fetcher.Form>
  );
}

理解度チェック

ルートのローダー関数が返したデータを読み取るフックはどれですか?

まとめ

React Router の Data API では、レンダリング前のデータ取得にローダーを、データの変更処理にアクションを使用します。コンポーネントでは、ローダーデータを useLoaderData() で、アクションの結果を useActionData() で、ナビゲーション状態を useNavigation() で読み取ります。

よくある質問

「LoadersとActions(Data Router API)」レッスンは無料ですか?

はい。「LoadersとActions(Data Router API)」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。

「LoadersとActions(Data Router API)」で何を学びますか?

loaderでrender前にルートデータを取得し、actionでフォーム送信を処理します。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

React Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「LoadersとActions(Data Router API)」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このReact Academyレッスンでコードを書いて実行できますか?

はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ネストしたルートとOutletレイアウト
  2. LoadersとActions(Data Router API)
  3. 保護されたルートとAuth Guard
  4. URL Search ParamsによるState管理
← React Academyに戻る