Forms are an essential part of any web application. In React, there are several ways to manage forms, from manual control to powerful libraries. In this article, we’ll explore four popular methods to handle forms in React, with practical examples for each.
1. Controlled Forms with React
React uses "controlled" inputs, where the input value is stored in the state.
import React, { useState } from 'react';
function BasicForm() {
const [form, setForm] = useState({ name: '', email: '' });
function handleChange(e) {
setForm({ ...form, [e.target.name]: e.target.value });
}
function handleSubmit(e) {
e.preventDefault();
console.log(form);
}
return (
<form onSubmit={handleSubmit}>
<input placeholder="TCHACA" name="name" value={form.name} onChange={handleChange} />
<input placeholder="ARROCHA@TCHACA.COM" name="email" value={form.email} onChange={handleChange} />
<button type="submit">Submit</button>
</form>
);
}
Highlights:
- Uses
event.target.name
for multiple inputs. - Inputs are 100% controlled by state.
2. Formik
Formik is a popular library that allows you to handle forms in a declarative way.
import { Formik, Form, Field } from 'formik';
function FormikForm() {
return (
<Formik
initialValues={{ name: '', email: '' }}
onSubmit={(values) => console.log(values)}
>
<Form>
<Field name="name" placeholder="Name" />
<Field name="email" placeholder="Email" />
<button type="submit">Submit</button>
</Form>
</Formik>
);
}
Highlights:
- Less boilerplate.
- Easy integration with validation tools.
3. Formik + Yup
Yup lets you define validation rules declaratively and works seamlessly with Formik.
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
const schema = Yup.object().shape({
name: Yup.string().required('Name is required'),
email: Yup.string().email('Invalid email').required('Email is required'),
});
function ValidatedForm() {
return (
<Formik
initialValues={{ name: '', email: '' }}
validationSchema={schema}
onSubmit={(values) => console.log(values)}
>
<Form>
<Field name="name" placeholder="Name" />
<ErrorMessage name="name" component="div" />
<Field name="email" placeholder="Email" />
<ErrorMessage name="email" component="div" />
<button type="submit">Submit</button>
</Form>
</Formik>
);
}
Highlights:
- Powerful and reusable validation.
- Instant feedback to users.
- More examples here
See this live:
4. React Hook Form
A lightweight and performant alternative with built-in validation support.
import { useForm } from 'react-hook-form';
function RHFForm() {
const { register, handleSubmit, formState: { errors } } = useForm();
function onSubmit(data) {
console.log(data);
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('name', { required: 'Name is required' })} placeholder="Name" />
{errors.name && <span>{errors.name.message}</span>}
<input {...register('email', { required: 'Email is required' })} placeholder="Email" />
{errors.email && <span>{errors.email.message}</span>}
<button type="submit">Submit</button>
</form>
);
}
Highlights:
- Better performance for large forms.
- Less code and more focus on productivity.
Conclusion
These four approaches range from basic to advanced and cover the most common use cases for handling forms in React. Choose the one that best fits your project's needs.
Top comments (10)
Great breakdown! React Hook Form made big forms so much easier for me, especially with those built-in validations - do you have a go-to for dynamic field arrays?
yeh. I like so much React Hook Form. About you question, do you have an example?
Great post.
Thanks bro
Good job!
Thank you!
Insane how much easier this makes form stuff, I’ve lost way too many hours to messy state bugs
Yes. I'm too. many many hours. rssr
From fully manual to library-powered, React offers many ways to build forms.
yes. for this I like so much React too