Tip: Implementation of Validators for React Hook Form

Tip: Implementation of Validators for React Hook Form

Takahiro Iwasa
(岩佐 孝浩)
Takahiro Iwasa (岩佐 孝浩)
2 min read
React

I wrote validator functions for React Hook Form which can be composed to meet your needs. Please refer to the official documentation for React Hook Form validation rules.

You can pull an example code used in this post from my GitHub repository.

Please create validators.ts with the following code.

import { RegisterOptions } from 'react-hook-form';

export const requiredValidator = (): RegisterOptions => {
  return { required: { value: true, message: 'Must be entered.' } };
};

export const minLengthValidator = (minLength: number): () => RegisterOptions => {
  return () => ({ minLength: { value: minLength, message: `Must be ${minLength} or more characters.` } });
};

export const maxLengthValidator = (maxLength: number): () => RegisterOptions => {
  return () => ({ maxLength: { value: maxLength, message: `Must be ${maxLength} or less characters.` } });
};

export const minValidator = (min: number): () => RegisterOptions => {
  return () => ({ min: { value: min, message: `Must be ${min} or larger.` } });
};

export const maxValidator = (max: number): () => RegisterOptions => {
  return () => ({ max: {value: max, message: `Must be ${max} or smaller.` } });
};

export const emailValidator = (): RegisterOptions => {
  // Based on https://learn.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format
  return { pattern: { value: /^[^@\s]+@[^@\s]+\.[^@\s]+$/, message: 'Must be a valid email.' } };
};

export const kanaValidator = (): RegisterOptions => {
  return { pattern: { value: /^[ァ-ヴ・ヲ-゚]*$/, message: 'Must be kana characters.' } };
};

export const fullWidthKanaValidator = (): RegisterOptions => {
  return { pattern: { value: /^[ァ-ヴ・]*$/, message: 'Must be full-width kana characters.' } };
};

export const halfWidthKanaValidator = (): RegisterOptions => {
  return { pattern: { value: /^[ヲ-゚]*$/, message: 'Must be half-width kana characters.' } };
};

export const composeValidators = (...validators: (() => RegisterOptions)[]) => {
  return validators.reduce((acc, cur) => ({ ...acc, ...cur() }), {});
};

Then, select validators you need and pass them to composeValidators.

import { useForm } from 'react-hook-form';
import { composeValidators, emailValidator, requiredValidator } from './validators';

export const HelloWorldPage: React.FC = () => {
  const { register, formState: { errors } } = useForm({ mode: 'all' });
  return (
    <form>
      <input type="text" { ...register('email', composeValidators(requiredValidator, emailValidator)) } />
      <p>
        <>{ errors.email?.message }</>
      </p>
    </form>
  );
};
Takahiro Iwasa
(岩佐 孝浩)

Takahiro Iwasa (岩佐 孝浩)

Software Developer at iret, Inc.
Architecting and developing cloud native applications mainly with AWS. Japan AWS Top Engineers 2020-2023