🙄
formState.isSubmittingがレンダリングしない
react-hook-formのformState.isSubmittingを使ってフォーム送信中にフォームを操作するUI(ボタン等)をdisabledにしたかったのだが、disabledになっていないように見えた。
結論
- formStateをちゃんとsubscribeしてる?
- submitが早すぎて見えてないだけじゃない?
コード
export default Page = () => {
const { handleSubmit, formState: {isSubmitting} } = useFormContext()
const onSubmit = () => {
console.log("submit")
}
return (
<form onSubmit={handleSubmit(onSubmit)} >
{/* form field */}
<button type="submit" disabled={isSubmitting}>submit</button>
</form>
)
}
これだとsubmitが早すぎて観測できないことがあるので、
const onSubmit = data => {
return new Promise((resolve) => {
setTimeout(() => resolve(), 1000);
});
};
これでも観測できない場合は、formStateオブジェクトを丸ごと呼び出しているかを確認する。
formStateはproxyでラップされている
無駄なレンダリングを防ぐためにformStateはプロキシでラップされている
= formStateはオブジェクトごとバッチで更新される
つまり、formStateの変更を反映したい場合はformState全体をサブスクライブする必要がある
useEffect(() => {
if (formState.errors.firstName) {
// do the your logic here
}
}, [formState]); // ✅
// ❌ formState.errors will not trigger the useEffect
// ❌ formState.isValid is accessed conditionally,
// so the Proxy does not subscribe to changes of that state
return <button disabled={!formState.isDirty || !formState.isValid} />;
// ✅ read all formState values to subscribe to changes
const { isDirty, isValid } = formState;
return <button disabled={!isDirty || !isValid} />;
参考
Discussion