はじめに
React19では、新たに<form action={非同期関数}>
の形式で、フォームアクションが追加されました
これにより、フォームの送信時に非同期関数を直接呼び出せるようになり、よりシンプルなコードが書けるようになります
本記事では、この新機能の使い方とその利便性について詳しく解説します
また、この新機能useFormStatus
というフォームの送信中の状態を取得するフックも追加されてより利便性が向上しました
formアクションの使用
以下の例では、フォーム送信時にhandleSubmit
関数が非同期に呼び出されます
React19の実装例
import { useState } from 'react';
import { useFormStatus } from 'react-dom';
async function handleSubmit(formData) {
const response = await fetch('/api/submit', {
method: 'POST',
body: formData
});
if (!response) {
throw new Error('Network response was not ok');
}
return await response.json();
}
function MyForm() {
const [status, setStatus] = useState(null);
const { isPending } = useFormStatus();
return (
<form action={handleSubmit} >
<input type="text" name="name" />
<button type="submit" disabled={isPending}>
{isPending ? 'Submitting...' : 'Submit'}
</button>
{status && <p>{status}</p>}
</form>
);
}
export default MyForm;
この実装の利点
- 簡潔なコード
- フォームの
action
属性に非同期関数を直接指定することで、コードが簡潔になり、読みやすさが向上します
- フォームの
- 非同期処理の簡素化
- フォーム送信時に非同期処理を簡単に組み込むことができ、従来のイベントハンドラを使う方法よりも直感的です
- 進行中状態の明示化
-
useFormStatus
フックを使用することで、フォーム送信中の状態をisPending
プロパティとして取得し、ボタンの状態を動的に変更できます
-
Reat18以前の実装方法
React18以前では、フォームの送信イベントをキャッチし、その中で非同期処理を行なっていました
React18以前の実装例
import { useState } from 'react';
async function handleSubmit(event) {
event.preventDefault();
const formData = new FormData(event.target);
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
});
if (!response.ok) {
throw new Error('Network response was not ok');
}
const result = await response.json();
return result;
}
function MyForm() {
const [status, setStatus] = useState(null);
const [isPending, setIsPending] = useState(false);
const handleFormSubmit = async (event) => {
event.preventDefault();
setIsPending(true);
try {
const result = await handleSubmit(event);
setStatus(`Success: ${result.message}`);
} catch (error) {
setStatus(`Error: ${error.message}`);
} finally {
setIsPending(false);
}
};
return (
<form onSubmit={handleFormSubmit}>
<input type="text" name="name" />
<button type="submit" disabled={isPending}>
{isPending ? 'Submitting... : 'Submit'}
</button>
{status && <p>{status}</p>}
</form>
);
}
React18以前では汎用的なuseState
を多用するのでどうしても分岐が多くなってしまいますね
まとめ
React19のformアクション機能により、フォームの非同期処理がより簡単かつ直感的に実装できるようになりました
この新機能とuseFormStatus
フックを活用することで状態管理が簡潔で可読性の高いコードを書けるようになり、開発者の負担を軽減することができるようになるでしょう
参考リンク