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を使用する前に、まずuseStateとuseRefを使ってフォーム送信をどのように処理するかを見てみましょう。
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を活用することで、応答性が高くメンテナンスしやすいフォームを作成できます。特に大規模なアプリケーションでは、頻繁なフォームのやり取りを効率的に処理できる点が大きなメリットです。