📝
React19で追加されたhooks触ってみた2(useFormStatus)
useFormStatus
直近の親のフォームに関するステータス情報を取得するために利用する。
このhooksを利用することで、form
要素の子として作成したコンポーネント(ボタンなど)は、props
で、ステータスを受け取ることなく、親のform
の状態を取得できる。
定義
const { pending, data, method, action } = useFormStatus();
返り値
pending
親の<form>
のaction
が実行中かどうかを表す値。
実行中=true
/実行していない=false
。
data
FormDataインターフェースを実装したオブジェクト。
親のform
要素がaction
を実行した際のデータを保持している。
親のform
要素がaction
を実行していないか、そもそも親にform
要素がない場合は、null
になる。
method
get
or post
の何れかの文字列。
親のform
要素がGET
とPOST
メソッドどちらを使用しているかを表す。
action
親のform
要素のaction
に渡された関数への参照。
子要素側で、親のform
のaction
を実行できる。
以下の場合、null
になる。
- 親に
form
要素がない。 - 親の
form
のaction
にstringの値を渡している。 - 親の
form
のaction
に何も渡していない
使用例
const SubmitButton = () => {
const { pending } = useFormStatus();
return (
<button type="submit" disabled={pending}>
送信
</button>
)
}
const Form = () => {
return (
<div>
<form action={action}>
<SubmitButton />
</form>
</div>
)
}
注意点
-
form
要素の子要素のコンポーネントで使用する必要がある。 - 親の
form
要素のステータス情報を取得するため、同じコンポーネントや子コンポーネント内でレンダーされたform
のステータス情報は取得できない。
const SubmitButton = () => {
const { pending } = useFormStatus();
return (
<button type="submit" disabled={pending}>
送信
</button>
)
}
const Form = () => {
// ❌ form要素と同じ階層にあるため、useFormStatusでステータス情報を取得できない
const { pending } = useFormStatus();
return (
<div>
<form action={action}>
{/* ✅ 親にform要素があるため、親のformのステータス情報をuseFormStatusで取得できる */}
<SubmitButton />
</form>
{/* ❌ form要素の外部のため、useFormStatusでステータス情報を取得できない */}
<SubmitButton />
</div>
)
}
- フォームのネスト時は、最も近い親の
form
要素のステータス情報を取得する
const Forms = () => {
return (
<form action={outerAction}>
<form action={innerAction}>
<StatusButton /> {/* 最も近い親のform要素のinnerActionのステータスを取得する */}
</form>
</form>
);
}
感想
フォームの送信ボタンなどを共通化したい場合などに便利なhooksだと感じた。
ただ、ほぼ使用することはないが、method
の値がpost
になるケースが、form
要素のmethod
属性にPOST
を設定した時のみだった。
また、action
属性とmethod
属性を同時に設定すると、以下のようなエラー表示されるため、action
属性のみを指定した場合に、POST
になるケースがわからなかった。
Cannot specify a encType or method for a form that specifies a function as the action.
React provides those automatically.
They will get overridden. Error Component Stack
参考
Discussion