問題
新規ユーザーを登録する画面を作成していて、登録ボタンを押すと、form内のデータが送信されてDBにデータが登録される部分を実装していました。
実際に画面上から登録ボタンを押すと、ボタンを押してもエラーが発生しないので、DB登録ができているのか確認をしたら登録ができていませんでした。
デバッグをするためconsole.logで登録ができたらログを表示するように設定をしてもログ自体も表示されませんでした。
エラーも出ない・デバッグもできない状況で原因がわかるまで少し時間を要したので共有します。
事象
問題のコードがこちら。
returnの中でreact-hook-formのformタグでinput要素と登録ボタンをを囲み、登録ボタンに関しては、react-router-domのLinkコンポーネントで囲み、登録ボタンが押下された後の遷移先を指定しています。
return (
<Card className="w-[350px]">
<CardHeader>
<CardTitle>新規ユーザー登録</CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit(onSubmit)}>
<div className="grid w-full items-center gap-6">
<div className="flex flex-col space-y-1.5">
<Label htmlFor="framework">Name</Label>
<Input
id="name"
placeholder="フルネームを入力"
{...register("name", { required: "名前の入力は必須です" })}
/>
{errors.name && (
<span className="text-red-500">{errors.name.message}</span>
)}
</div>
...一部省略
<CardFooter className="flex justify-end mt-4">
<Link to="/login" className="" style={{ textDecoration: "none" }}>
<button type="submit" className="btn btn-success">
新規ユーザー登録
</button>
</Link>
</CardFooter>
</form>
</CardContent>
</Card>
);
解決法
結論からいうと、react-router-domのLinkコンポーネントを使用して登録後に別ページへ遷移する設定をしていましたが、これがReact-hook-formのformと競合していることが問題だったようです。
今回はLinkコンポーネントの使用をやめて、react-router-domのuseNavigateコンポーネントを使用することで解決することができました。
詳細を確認してみると、Linkコンポーネントはクリックイベントをキャッチして新しいページへの遷移を行うのですが、formの送信イベントよりも早く処理されてしまうようです。
そうするとformの中身がないまま送信処理がされてしまうので、エラーは出ないがDBに登録するデータがないので登録自体ができていないという今回の事象に繋がってしまったということです。
おわりに
エラーが出ないので何が原因かわからなかったですが、コンポーネントの競合が起こることを予想できませんでした。イベントの処理手順など学びつつ実装ができるように勉強を続けていきたいと思います!