This content originally appeared on Bits and Pieces - Medium and was authored by Madushika Perera
Understanding React Hook Form and how it stands out from other form libraries
Over the years, I’ve been using React inbuilt forms, Formik, and Redux-Form. But I still found it challenging to handle events like onBlur, onChange, touch, and onSubmit. In my endeavor to find an alternative, I hit upon the React Hook Form library.
First of all, to get a better understanding, let’s look at an example with React Hook Form and compare it with Formik and Redux-Form.
Building a form with React Hook Form
Now let’s install React Hook Form and build a small form comparing the source code with other libraries. You can install react-hook-form library, either using NPM npm install react-hook-formor Yarn yarn add react-hook-form.
In this example, I will use the react-hook-form API’s register and handleSubmit to build the form.
import React from "react";
import { useForm } from "react-hook-form";
export default function App() {
const { register, handleSubmit } = useForm();
const onSubmit = data => console.log(data); //prints {"firstName":"something","gender":"male"}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input name="firstName" ref={register} />
<select name="gender" ref={register}>
<option value="female">female</option>
<option value="male">male</option>
<option value="other">other</option>
</select>
<input type="submit" />
</form>
);
}
Here, you can see that the register is passed to the ref of each uncontrolled form element. This will make its value available for both the form validation and submission. Note that it is essential to add a name attribute with a unique identifier while using the register.
Tip: Author, version, and share independent React components with Bit.
- Learn more about Bit Harmony (beta) for React here:
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!
- React Hook Form — An Elegant Solution to Forms in React
- Build Awesome Forms In React Using Redux-Form
- Creating React Forms with Formik
Why You Should Choose React Hook Form Over Formik and Redux-Form was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Bits and Pieces - Medium and was authored by Madushika Perera
Madushika Perera | Sciencx (2021-03-15T22:16:51+00:00) Why You Should Choose React Hook Form Over Formik and Redux-Form. Retrieved from https://www.scien.cx/2021/03/15/why-you-should-choose-react-hook-form-over-formik-and-redux-form/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.