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