3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【React】フォームを使うなら、react-hook-formがいいよ

Posted at

はじめに

多くのサイトにはフォームが存在していると思います。
Qiitaなどのユーザー投稿型のサイトもそうですし、ブログなどの静的サイトであっても、問い合わせページなどではフォームがあったりするかと思います。

では、Reactでフォームを取り扱うときどうすればいいでしょうか?

従来通り、useStateやuseRefを用いてフォームのvalueを管理し、APIを叩く方法が真っ先に思いつくかと思います。

ただ、ステートの管理やエラーのハンドリングなどが大変になってきたりします。

そこで出てくるのがフォームライブラリ。

2022現在、Reactではreact-hook-formというのが人気だったりします。

今回はこのreact-hook-formのお話

react-hook-formとは?

上に書いたように、フォームのステートやエラーの管理をしてくれます。
ドキュメントが日本語であるというのもいいところですね。

今回は個人的にいいなと思うことをピックアップして話します。

基本

import { useState } from "react";
import { useForm } from "react-hook-form";
import Header from "./Header";

export function App() {
  const { register, handleSubmit } = useForm();
  const onSubmit = () => {
    // api叩いたりする
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Header />
      <input {...register("firstName")} placeholder="First name" />
      <select {...register("category", { required: true })}>
        <option value="">Select...</option>
        <option value="A">Option A</option>
        <option value="B">Option B</option>
      </select>
      <textarea {...register("aboutYou")} placeholder="About you" />
      <p>{data}</p>
      <input type="submit" />
    </form>
  );
}

これだけだと、ステートの管理をしてくれるものぐらいにしか恩恵が感じられなさそうですが、他にも色々な機能を持っているので紹介していきます。

バリデーションとエラーハンドリング

フォームを登録する際にバリデーションロジックを組み込むことができます。
また、ErrorMessageというエラーハンドリング用のコンポーネントを使えば、エラー状態をハンドリングして表示を切り替えて来れたりします。

import React from "react";
import { useForm } from "react-hook-form";
import { ErrorMessage } from '@hookform/error-message';

export default function App() {
  const { register, formState: { errors }, handleSubmit } = useForm();
  const onSubmit = data => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("singleErrorInput", { required: "This is required." })} />
      <ErrorMessage errors={errors} name="singleErrorInput" />
      
      <ErrorMessage
        errors={errors}
        name="singleErrorInput"
        render={({ message }) => <p>{message}</p>}
      />
      
      <input type="submit" />
    </form>
  );
}

dirtyやisValidなどのステート提供

useStateのhooksが返してくれるのは、errorオブジェクトだけではありません。

  • isDirty: フォームに触れられたかどうか
  • isValid: バリデーションが通っているか

なども返してくれます。

例えば、フォームに一度は触って、バリデーションが通らないと送信ボタンを押せないようにする。
みたいなロジックもすぐに実現可能です。

const { formState: { isDirty, isValid } } = useForm();
return <button disabled={!isDirty || !isValid} />;

また、dirtyFieldsなど他のAPIも提供されており、一つ一つのフォームの状態を柔軟にとってくることができます。

この辺りのステートを自分で管理しようとするとめちゃくちゃ大変なので助かりますね。

Submit状態を管理してくれる

上に同じく、formStateという中に、isSubmittedisSubmitSuccessfulなどが入ってます。

なので、フォーム送信が成功したタイミングでリダイレクトさせる。

みたいな処理も楽に書くことができます。

const { push } = useRouter()
const { formState: { isSubmitSuccessful } } = useForm();

useEffect(()) => {
  if (isSubmitSuccessful) {
    push('/success')
  }
}, [isSubmitSuccessful]}

onSubmitの中に処理を詰め込まず、関心ごとを分離してコードを書けるのでとても良いですね。

他にも、フォーム送信後にフォーム内容をリセットしたいなどの場合もresetFiledというAPIがあるのでそれを使えばいけたりします。

FormProvider

フォームのステートやエラーなどを配布するProviderと取り扱うhooksを提供してくれます。
大体はフォームを別コンポーネントで切り出したりするので、子コンポーネント側でフォームのエラー状態のハンドリングやステートが柔軟に取り出して来れるのはいいことですね

import React from "react";
import { useForm, FormProvider, useFormContext } from "react-hook-form";

export default function App() {
  const methods = useForm();
  const onSubmit = data => console.log(data);

  return (
    <FormProvider {...methods} > // pass all methods into the context
      <form onSubmit={methods.handleSubmit(onSubmit)}>
        <NestedInput />
        <input type="submit" />
      </form>
    </FormProvider>
  );
}

function NestedInput() {
  const { register } = useFormContext(); // retrieve all hook methods
  return <input {...register("test")} />;
}

まとめ

まだまだ紹介できていないこともありますが、個人的にいいなと思うことをピックアップしてreact-hook-formについて書いてみました。

ぜひ色々公式ドキュメントをみながら、使ってみてください

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?