事象
以下のコードで期待していた挙動が起こらずに困っていた
🧐 期待していた挙動
- react-hook-formの
handleSubmit
を使って、フォームのデータを取得 - フォームのデータを使って、データベースに値を保存
- 叩いたレスポンスのidを使って、
router.push
を使って、ページ遷移
❌ 実際の挙動
- react-hook-formの
handleSubmit
を使って、フォームのデータを取得ができた - データベースに値が保存されない
- ページ遷移はされずに、同じページが表示されつづけ、URLにはフォームデータがクエリパラメータとして渡されている
const OnSubmit = () => {
handleSubmit((data)=>{
何かのAPI(data).then(res=>{
router.push(`/${res.id}`)
})
})
}
<form onSubmit={OnSubmit}>
<input type="text" vale="name" ...register("name")/>
<button type="submit">submit</button>
</form>
問題点
1. <form>
タグを使用した時に起こるブラウザのデフォルト機能
-
<form>
タグのonSubmit
は、ブラウザはデフォルトの動作としてフォームを送信し、ページをリロードする - この時、フォームのデータは URL のクエリパラメータとしてエンコードされ、送信される
- これが、URLにフォームデータが表示され、ページ遷移が行われない「実際の挙動の③」の原因
2. react-hook-formのhandleSubmit
の返り値の仕様
- handleSubmitは、引数で関数を受け取り、さらにその処理を走らせる新たな関数を返り値として返す
- そのため、返された関数に対して()で実行命令を与えることで、関数が呼ばれるようになる
解決策
-
handleSubmit(function)
でOnSubmitを囲ってあげる(2に関する問題の解決) - また、
handleSubmit(function)
を使うことで、フォームのデフォルト動作がキャンセルされる(1に関する問題も同時に解決する)(event.preventDefault()と同じ効果)
const onSubmit = () => {
何かのAPI(data).then(res=>{
router.push(`/${res.id}`)
})
}
<form onSubmit={handleSubmit(onSubmit())}> ///eventを引数に
<input type="text" vale="name" ...register("name")/>
<button type="submit">submit</button>
</form>
参考