2
2

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のuseActionStateフックを理解する

Last updated at Posted at 2025-01-31

ReactのuseActionStateフックは、フォームの状態を管理するための高度なツールであり、動的なフォーム送信を効率的に処理できます。React 19で利用可能になり、JavaScriptバンドルが完全に読み込まれる前でもフォームをインタラクティブにすることができます。特に、React Server Components(RSC)と組み合わせることで、応答時間を最適化し、ユーザーエクスペリエンスを向上させる強力なツールです。

この記事では、useActionStateフックの概要を説明し、従来のフォーム送信方法をどのように改善できるかを実際のコードを使って紹介します。

useActionStateとは?

useActionStateフックを使用すると、フォームのアクションの結果に基づいてコンポーネントの状態を更新できます。これにより、フォーム送信をより柔軟に制御でき、動的な状態管理が可能になります。

フックの構文

const [state, formAction, isPending] = useActionState(fn, initialState, permalink?);
  • fn: フォーム送信時に呼び出される関数。前の状態とフォームデータを引数として受け取ります。
  • initialState: フォームアクションが実行される前の初期状態。
  • permalink(オプション): フォームが変更するURL。動的なコンテンツがあるページに便利です。
  • state: 現在のフォームの状態。
  • formAction: フォームのactionまたはformActionプロパティに渡す新しいアクション。
  • isPending: アクションが進行中であるかを示すブール値。

useStateとuseRefを使った従来のフォーム送信

useActionStateを使用する前に、まずuseStateuseRefを使ってフォーム送信をどのように処理するかを見てみましょう。

import { useState, useRef, RefObject } from "react";

function FeedbackForm() {
  const [feedback, setFeedback] = useState("");
  const formRef: RefObject<HTMLFormElement | null> = useRef(null);

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const formData = new FormData(formRef.current || undefined);
    const message = formData.get("feedback");

    // サーバー遅延のシミュレーション
    await new Promise((resolve) => setTimeout(resolve, 1000));

    setFeedback(`受信: ${message}`);
  }

  return (
    <form ref={formRef} onSubmit={handleSubmit}>
      <textarea name="feedback" placeholder="フィードバックを入力" />
      <button type="submit">送信</button>
      <p>{feedback}</p>
    </form>
  );
}

useActionStateを使った改善

次に、useActionStateを使用して、フォームをよりインタラクティブにし、サーバーアクションを活用する方法を紹介します。

import { useActionState } from "react";

async function submitFeedback(prevState: unknown, formData: FormData) {
  const message = formData.get("feedback");
  await new Promise((resolve) => setTimeout(resolve, 1000)); // サーバー遅延のシミュレーション
  return `受信: ${message}`;
}

function FeedbackForm() {
  const [feedback, formAction, isPending] = useActionState(submitFeedback, "");

  return (
    <form action={formAction}>
      <textarea name="feedback" placeholder="フィードバックを入力" />
      <button type="submit">送信</button>
      {isPending && <p>送信中...</p>}
      {!isPending && <p>{feedback}</p>}
    </form>
  );
}

主な改善点

  • 簡潔な状態管理: useActionStateにより、useStateを使わずにフォーム状態を動的に管理。
  • 自動フォーム処理: フォームの送信処理を自動化し、イベントリスナーの設定が不要に。
  • 保留状態の管理: isPendingフラグを使用して、フォーム送信中の状態を示すことでUXを向上。

まとめ

ReactのuseActionStateフックは、フォームアクションの結果に基づいて状態を管理できる便利なツールです。従来のフォーム送信方法からuseActionStateに移行することで、コードを簡潔にし、インタラクティブ性とユーザーエクスペリエンスを向上させることができます。

useActionStateを活用することで、応答性が高くメンテナンスしやすいフォームを作成できます。特に大規模なアプリケーションでは、頻繁なフォームのやり取りを効率的に処理できる点が大きなメリットです。

2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?