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 KAKEHASHI Inc.
Involved in the requirements definition, design, and development of cloud-native applications using AWS. Now, building a new prescription data collection platform at KAKEHASHI Inc. Japan AWS Top Engineers 2020-2023.