Photo by Olav Ahrens Røtne on Unsplash
As the forms in our React project become more and more complex, the question arise how we can make our lives easier. This is where third-party libraries come to the rescue. The next main question is which form library is better. In this article, we are going to take a look at three of the best React form libraries.
React Hook Form
React hook form
React Hook Form — performant, flexible and extensible forms with easy-to-use validation. It’s one of the most popular React Form library with close to 31.4k stars on GitHub. Also it has 2.6 million user downloads on npm. Why should we use React Hook Form:
- Super light — it is a tiny library without any dependencies
- Performance —minimizes the number of re-renders, minimizes validation calculations and speeds up mounting
- HTML standard — using existing HTML markup and validation your forms with our API
- Adoptable — it can be easily accepted without other dependencies
- The community — has a great community to make every React developer’s life easier Install
npm install react-hook-form
Usage
import { useForm } from "react-hook-form";
export default function App() {
const {
register,
handleSubmit,
watch,
formState: { errors },
} = useForm();
const onSubmit = (data) => console.log(data);
console.log(watch("example")); // watch input value by passing the name of it
return (
/* "handleSubmit" will validate your inputs before invoking "onSubmit" */
<form onSubmit={handleSubmit(onSubmit)}>
{/* register your input into the hook by invoking the "register" function */}
<input defaultValue="test" {...register("example")} />
{/* include validation with required or other standard HTML validation rules */}
<input {...register("exampleRequired", { required: true })} />
{/* errors will return when field validation fails */}
{errors.exampleRequired && <span>This field is required</span>}
<input type="submit" />
</form>
);
}
Formik
Formik is one of the most popular open source form library for React and React Native. It has 31.4k stars on GitHub and 2.1 million user downloads on npm. Why we should Formik:
- Declarative — it takes care of the repetitive and annoying stuff — keeping track of values/errors/visited fields, validation, and handling submission
- Intuitive — Formik makes it easy to debug, test and analyze your forms, you just work with simple React state and props
- Adoptable — it does not use external state management libraries such as Redux or MobX. Install
npm install formik --save
Usage
import React from "react";
import { Formik, Form, Field, ErrorMessage } from "formik";
export function Basic() {
return (
<div>
<h1>Any place in your app!</h1>
<Formik
initialValues={{ email: "", password: "" }}
validate={(values) => {
const errors = {};
if (!values.email) {
errors.email = "Required";
} else if (
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
) {
errors.email = "Invalid email address";
}
return errors;
}}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 400);
}}
>
{({ isSubmitting }) => (
<Form>
<Field type="email" name="email" />
<ErrorMessage name="email" component="div" />
<Field type="password" name="password" />
<ErrorMessage name="password" component="div" />
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</Form>
)}
</Formik>
</div>
);
}
React Final Form
React Final Form — high performance subscription-based form state management for React. It has 7.1k stars on GitHub and 350k user downloads on npm. Why we should use React Final Form:
- Zero dependencies — it has only two peer dependencies React and Final Form weighing just 3.4KB compressed (plus 5.6KB compressed for Final Form)
- High performance — this allows you to fine-tune which form elements are notified of changes to the form’s state Install
npm install --save final-form react-final-form
Usage
import { Form, Field } from "react-final-form";
export function ReactFinalForm() {
return (
<Form
onSubmit={onSubmit}
validate={validate}
render={({ handleSubmit }) => (
<form onSubmit={handleSubmit}>
<h2>Simple Default Input</h2>
<div>
<label>First Name</label>
<Field
name="firstName"
component="input"
placeholder="First Name"
/>
</div>
<h2>An Arbitrary Reusable Input Component</h2>
<div>
<label>Interests</label>
<Field name="interests" component={InterestPicker} />
</div>
<h2>Render Function</h2>
<Field
name="bio"
render={({ input, meta }) => (
<div>
<label>Bio</label>
<textarea {...input} />
{meta.touched && meta.error && <span>{meta.error}</span>}
</div>
)}
/>
<h2>Render Function as Children</h2>
<Field name="phone">
{({ input, meta }) => (
<div>
<label>Phone</label>
<input type="text" {...input} placeholder="Phone" />
{meta.touched && meta.error && <span>{meta.error}</span>}
</div>
)}
</Field>
<button type="submit">Submit</button>
</form>
)}
/>
);
}
Conclusion
Thanks for reading, I hope you found this piece useful. Happy coding!