DEV Community

wattanx
wattanx

Posted on

I made a simple validation library for React.

In developing a web application using React, I encountered the problem of how to validate a Form.

I've been comparing and reviewing various libraries such as React Hook Form and Formik.
However, I decided to create my own library because I didn't need such a big feature and just wanted to be able to do simple validation.

https://github.com/wattanx/react-svl

Features I wanted.

What I wanted as a feature of the validation library was

  • Ability to specify validation rules
  • Use Controlled Components
  • Required check, minimum/maximum value check, maximum/minimum character length check

Usage

Install it first.

npm install react-svl
Enter fullscreen mode Exit fullscreen mode

or

yarn add react-svl react
Enter fullscreen mode Exit fullscreen mode

We will use Chakra UI to explain.

import { Box } from '@chakra-ui/layout';
import { Input } from '@chakra-ui/input';
import { FormControl, FormErrorMessage, FormLabel } from '@chakra-ui/form-control';
import { useForm } from 'react-svl';

export const ValidationExample = () => {
  const { errors, values, setFieldValue, validateField } = useForm({
    initialValues: {
      FirstName: '',
      Password: '',
    },
    validationRules: {
      FirstName: {
        isRequired: true,
      },
      Password: {
        minLength: 8,
      },
    },
  });
  return (
    <Box>
      <FormControl isInvalid={errors.FirstName.isInValid}>
        <FormLabel>First Name</FormLabel>
        <Input
          value={values.FirstName}
          onChange={(e) => setFieldValue('FirstName', e.currentTarget.value)}
          onBlur={() => validateField('FirstName')}
        />
        <FormErrorMessage>{errors.FirstName.isRequired?.message}</FormErrorMessage>
      </FormControl>
      <FormControl isInvalid={errors.Password.isInValid}>
        <FormLabel>Password</FormLabel>
        <Input
          value={values.Password}
          onChange={(e) => setFieldValue('Password', e.currentTarget.value)}
          onBlur={() => validateField('Password')}
        />
        <FormErrorMessage>{errors.Password.minLength?.message}</FormErrorMessage>
      </FormControl>
    </Box>
  );
};
Enter fullscreen mode Exit fullscreen mode

One Custom Hooks is imported from react-svl.

useForm is a Hooks that provides functions needed for validation and setting validation rules.

Details

Setting up validation rules

First, we will set the validation rules and initial values.

We will set the initial values in initialValues and the validation rules in validationRules.
This was implemented to satisfy the feature we wanted, to be able to specify validation rules.

const { errors, values, setFieldValue, validateField } = useForm({
  initialValues: {
    FirstName: "",
    Password: "",
  },
  validationRules: {
    FirstName: {
      isRequired: true,
    },
    Password: {
      minLength: 8,
    },
  },
});
Enter fullscreen mode Exit fullscreen mode

The following types have been created so that they can be set to type safe on input.

export type UseFormProps<T> = {
  validationRules: ValidationRule<T>;
  initialValues: T;
};

export function useForm<T extends { [key: string]: any }>({
  initialValues,
  validationRules,
}: UseFormProps<T>);
Enter fullscreen mode Exit fullscreen mode

The following items can be set as validation rules.

property type description
isRequired boolean Required or not
max number Maximum value
min number Minimum value
maxLength number Maximum text length
minLength number Minimum text length
validate (value: T[keyof T]) => boolean Custom rule(true: Error、false: no error)

Change State

You can use setFieldValue to change the State.

<Input value={values.FirstName} onChange={(e) => setFieldValue('FirstName', e.currentTarget.value)} />
Enter fullscreen mode Exit fullscreen mode

Execute Validate

Using validateField will execute the validation.

<Input
  value={values.FirstName}
  onChange={(e) => setFieldValue('FirstName', e.currentTarget.value)}
  onBlur={() => validateField('FirstName')}
/>
Enter fullscreen mode Exit fullscreen mode

Default Error Message

You can use errors.property_name.rules.name.message.

<FormControl isInvalid={errors.FirstName.isInValid}>
  <FormLabel>First Name</FormLabel>
  <Input
    value={values.FirstName}
    onChange={(e) => setFieldValue("FirstName", e.currentTarget.value)}
    onBlur={() => validateField("FirstName")}
  />
  <FormErrorMessage>{errors.FirstName.isRequired?.message}</FormErrorMessage>
</FormControl>
Enter fullscreen mode Exit fullscreen mode

It also sets the default message for each validation rule, as shown below. (None in the case of custom rule)

Rule Error Message
isRequired {property name} is required.
max {property name} must be less than or equal to {Maximum value}.
min {property name} must be greater than or equal to {Minimum value}.
maxLength {property name} must be less than or equal to {Maximum text length} characters.
minLength {property name} must be {Minimum text length} characters or more.

Demo

The source code introduced so far looks like the following when actually run.

@codesandbox

Top comments (0)