9
7

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-hook-formで入力内容によってバリデーションする方法

Last updated at Posted at 2023-02-07

react-hook-formはReact用のフォームライブラリです。簡単に入力フォームなどの実装ができます。
必須項目などの簡単バリデーションの他に、入力内容によってバリデーションすることも可能です。本記事ではreact-hook-formでのバリデーションの設定方法について解説しています。

react-hook-formのインストールなど

インストールのコマンドは下記の通りです。

npm install react-hook-form
#OR
yarn add react-hook-form 

react-hook-formの基本的なバリデーション

react-hook-formには下記などの良く利用するバリデーションが最初から用意されています。

  • required: 必須
  • maxLength: 最大文字数
  • minLenght: 最小文字数
  • pattern: パターン(メールアドレスや正規表現などのパターンで使える)

それぞれをフォームで設定するだけで簡単に利用できます。

<input
  {...register('name', {
    required: '必須入力',
    maxLength: {
      value: 50,
      message: '最大50文字です'
    },
    pattern:
      /^[A-Za-z0-9]{1}[A-Za-z0-9_.-]*@{1}[A-Za-z0-9_.-]+.[A-Za-z0-9]+$/
  })}
  type="text"
/>

入力内容によってフォームをバリデーションする方法

続いて入力内容によってフォームをバリデーションする方法になります。コード全体は下記です。

import dayjs from 'dayjs'
import { useForm } from 'react-hook-form'

type Form = {
  name: string
  email: string
  text: string
  check: boolean
}

const Form = () => {
  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm<Form>()

  const submit = (data: Form) => {
    console.log(Form)
  }

  return (
    <>
      <form onSubmit={handleSubmit(submit)}>
        <div>
          <input
            {...register('name', {
              required: '必須入力',
              maxLength: {
                value: 50,
                message: '最大50文字です'
              }
            })}
            type="text"
          />
          {errors.name && <span>{errors.name.message}</span>}
        </div>
        <div>
          <input
            {...register('email', {
              required: '必須入力',
              maxLength: {
                value: 50,
                message: '最大50文字です'
              }
            })}
            type="email"
          />
          {errors.email && <span>{errors.email.message}</span>}
        </div>
        <div>
          <textarea
            {...register('text', {
              required: '必須入力',
              // 入力内容によってバリデーションをする
              validate: (data) => {
                if (data === 'hoge') {
                  return 'NGワードです'
                }
                if (!dayjs(data).isValid()) {
                  return '日付の形式が違います'
                }
              }
            })}
          ></textarea>
          {errors.text && <span>{errors.text.message}</span>}
        </div>
        <div>
          <input
            {...register('check', {
              required: '必須入力'
            })}
            type="checkbox"
          />
          {errors.check && <span>{errors.check.message}</span>}
        </div>
        <div>
          <input type="submit" value="送信" onSubmit={handleSubmit(submit)} />
        </div>
      </form>
    </>
  )
}

export default Form

ユーザーの入力した値によって細かにバリデーションする場合は、valideteに設定します。
returnでエラーメッセージを返すことでエラーとして表示されます。
validateのコールバック関数の引数には、フォームに入力された値が入ってきます。
値によってバリデーションをして返すエラーを変えたりできます。
例えばDay.jsなどの日付用のライブラリを使って日付のチェックなども可能です。

validate: (data) => {
  if (!dayjs(data).isValid()) {
    return '日付の形式が違います'
  }
}

MUI(Material UI)とreact-hook-formでの実装例

ReactのUIフレームワークであるMUIとreact-hook-formを組み合わせと時の実装例になります。

import { Box, Button, Container, TextField } from '@mui/material'
import dayjs from 'dayjs'
import { Controller, useForm } from 'react-hook-form'

type Form = {
  name: string
  email: string
  text: string
  check: boolean
}

const Form = () => {
  const { control, handleSubmit } = useForm<Form>()

  const submit = (data: Form) => {
    console.log(data)
  }

  return (
    <Container>
      <Box component="form" onSubmit={handleSubmit(submit)}>
        <Box mb={4}>
          <Controller
            name="name"
            control={control}
            defaultValue=""
            rules={{
              required: { value: true, message: '必須入力です' },
              validate: (data) => {
                if (data === 'hoge') {
                  return 'NGワードです'
                }
                if (!dayjs(data).isValid()) {
                  return '日付の形式が違います'
                }
              }
            }}
            render={({ field, formState: { errors } }) => (
              <TextField
                {...field}
                fullWidth
                label="テキスト"
                error={errors.name ? true : false}
                helperText={errors.name?.message as string}
              />
            )}
          />
        </Box>
        <Box textAlign="right">
          <Button variant="contained" onClick={handleSubmit(submit)}>
            送信
          </Button>
        </Box>
      </Box>
    </Container>
  )
}

export default Form

react-hooks-form-validate2.png

参考

9
7
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
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?