Why You Should Choose React Hook Form Over Formik and Redux-Form
By: Madushika Perera
Tags: JavaScript, React Hook Form, Redux Form, React Hook, Formik

How to Validate the Form Fields?

It’s relatively easier to handle form validation in React Hook Form using the register hook. It also supports basic validation attributes such as required, min, max, minLength, maxLength, pattern, and validate. The code below demonstrates to perform validation using the register method.

<input name="firstName"

ref={register({ required: true, maxLength: 20 })} /> <input name="lastName"

ref={register({ pattern: /^[A-Za-z]+$/i })} /> <input name="age" type="number"

ref={register({ min: 18, max: 99 })} />

React Hook Form also supports schema validation by providing your schema to useForm as an optional config. We can also consider several schema designing libraries. For example, let’s use yup to create a custom schema for the form validation and pass it down to the form using the resolver property available in the useForm.

import React from "react";

import { useForm } from "react-hook-form";

import { yupResolver } from '@hookform/resolvers/yup';

import * as yup from "yup";



const schema = yup.object().shape({

firstName: yup.string().required(),

age: yup.number().positive().integer().required(),

}); export default function App() {

const { register, handleSubmit} = useForm({

resolver: yupResolver(schema)

});

const onSubmit = data => console.log(data);



return (

<form onSubmit={handleSubmit(onSubmit)}>

<input type="text" name="firstName" ref={register} />

<input type="text" name="age" ref={register} />

<input type="submit" />

</form>

);

}

Handling Errors

Handling errors in the form is considerably easy. The useForm hook provides a prop called error, which gives out the errors of the form fields. You can display the errors by referring to the unique name of each form field.

import React from "react";

import { useForm } from "react-hook-form";



export default function App() {

const { register, errors, handleSubmit } = useForm();



return (

<form onSubmit={handleSubmit(onSubmit)}>

<Input name="firstName" ref={register({ required: true })} />

{errors.firstName && "First name is required"}

<Input name="lastName" ref={register({ required: true })} />

{errors.lastName && "Last name is required"}

<input type="submit" />

</form>

);

}

Comparison with Formik and Redux-Forms

Let’s look at a form built using Formik with some basic validation and form submit event.

import React from 'react';

import { Formik, Form, Field, ErrorMessage } from 'formik'; const Basic = () => (

<div>

<h1>Any place in your app!</h1>

<Formik

initialValues={{ email: '', password: '' }}

validate={values => {

const errors = {};

if (!values. firstName ) {

errors.email = 'Required';

} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)) { errors.email = 'Invalid email address';

} else if (age>0){

errors.age = 'Age Should be grater than 0';

}

return errors;

}} onSubmit={(values, { setSubmitting }) => {

setTimeout(() => {

alert(JSON.stringify(values, null, 2));

setSubmitting(false);

}, 400);

}}>

{({ isSubmitting }) => (

<Form>

<Field type="text" name=" firstName " />

<ErrorMessage name=" firstName " component="div" />

<Field type="text" name=" age " />

<ErrorMessage name=" age " component="div" />

<button type="submit" disabled={isSubmitting}>

Submit

</button>

</Form>

)}

</Formik>

</div>

);

export default Basic;

In this code example, you can see that Formik uses a significant amount of boilerplate code compared to React Hook Form. In Formik, we need to handle the validation ourselves wherein React Hook Form has inbuilt methods via register to handle validations.

Now let’s consider a code example of Redux-Form with some basic validation for a form submit event.

import React from "react";

import { Provider } from "react-redux";

import { Field, reduxForm } from "redux-form";

import store from "./store";



const validate = values => {

const errors = {};



if (!values.firstName) {

errors.username = "Required";

} else if (values.age>0) {

errors.username = "Age should be greater than 0";

}



if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.firstName)) {

errors.email = "Invalid firstName pattern";

}



return errors;

};



const renderField = ({ input, label, type, meta: { touched, error } }) => (

<>

<input {...input} placeholder={label} type={type} />

{touched && error && <span>{error}</span>}

</>

);



const Form = props => {

const { handleSubmit } = props;

const onSubmit = values => console.log(values);



return (

<form onSubmit={handleSubmit(onSubmit)}>

<Field name="firstName" type="text" component={renderField} label="Email" />

<Field name="age" type="text" component={renderField} label="Age" />



<button type="submit">Submit</button>

</form>

);

};



const FormRedux = reduxForm({ form: "syncValidation", validate })(Form);



const Example = () => (

<Provider store={store}>

<FormRedux />

</Provider>

);

This example shows that Redux-Form requires quite a lot of boilerplate code just like Formik. It also requires Redux to be integrated along with it. So it's not advisable to use it in an application that doesn't use Redux for state management.

Unlike other libraries, React Hook Form reduces the amount of code you need to handle form events. Besides, there are several other benefits listed below.

1. Isolate Component Re-Rendering

React Hook Form isolates the component and avoids the other components from re-rending. This feature will improve the performance by avoiding unwanted rendering in other child components. However, libraries like Formik and Redux-Form re-render the other child components along with the form component.

2. Reduce Rendering

Besides isolating the component, it also limits its own (form components) form re-rendering on particular events such as onChange,onBlur, etc.

3. Faster Mounting

Mounting time is about 13% faster than Formik and 25% faster than Redux-Form. In other words, the form’s DOM elements will be inserted into the DOM tree quicker, leading to fast rendering compared with other libraries.

4. Input Change Subscriptions

React Hook Form allows you to subscribe to each input element without going through the re-rendering of each element inside the form component.

5. Typescript Support

React Hook Form is built with TypeScript and can define a FormData type to support form values.

6. Less Code to Maintain

Less code leads to fewer bugs!. The React Hook Form provides a hook called useForm(), consisting of methods and props handleSubmit, register, and errors. They would handle the submit events, the input via refs using register, and display any errors. However, in the other two libraries, you need to write your custom handlers for events and validations.

Conclusion

In conclusion, the React Hook Form library makes maintaining forms in React easier with simplified code. It offers support for React Hooks and Typescript out of the box. You can find more information on React Hook Form by referring to its documentation.

Thank you for taking the time to read this. I would like to see your questions and comments on the topic given in the comments below.

Cheers!