Tip: Implementation of Validators for React Hook Form
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>
);
};