Forms in React are used to capture user input and handle it effectively within the application. React provides a way to manage form elements such as input, select, and textarea through controlled components, which means that form data is handled by the state in React. Here’s a comprehensive guide to understanding and working with forms in React:
In a controlled component, form data is handled by the component’s state. The state is the single source of truth, and the input elements get their values from the state and update the state on every change.
import React, { useState } from 'react';
function ControlledForm() {
const [formData, setFormData] = useState({
name: '',
email: ''
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value
});
};
const handleSubmit = (e) => {
e.preventDefault();
console.log('Form data submitted:', formData);
};
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" name="name" value={formData.name} onChange={handleChange} />
</label>
<br />
<label>
Email:
<input type="email" name="email" value={formData.email} onChange={handleChange} />
</label>
<br />
<button type="submit">Submit</button>
</form>
);
}
export default ControlledForm;
Uncontrolled components allow the form data to be handled by the DOM itself. React provides a way to access form values using refs
.
import React, { useRef } from 'react';
function UncontrolledForm() {
const nameRef = useRef();
const emailRef = useRef();
const handleSubmit = (e) => {
e.preventDefault();
console.log('Form data submitted:', {
name: nameRef.current.value,
email: emailRef.current.value
});
};
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" ref={nameRef} />
</label>
<br />
<label>
Email:
<input type="email" ref={emailRef} />
</label>
<br />
<button type="submit">Submit</button>
</form>
);
}
export default UncontrolledForm;
When handling multiple inputs, it is common to use a single change handler and update the state accordingly.
import React, { useState } from 'react';
function MultipleInputsForm() {
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: ''
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value
});
};
const handleSubmit = (e) => {
e.preventDefault();
console.log('Form data submitted:', formData);
};
return (
<form onSubmit={handleSubmit}>
<label>
First Name:
<input type="text" name="firstName" value={formData.firstName} onChange={handleChange} />
</label>
<br />
<label>
Last Name:
<input type="text" name="lastName" value={formData.lastName} onChange={handleChange} />
</label>
<br />
<label>
Email:
<input type="email" name="email" value={formData.email} onChange={handleChange} />
</label>
<br />
<button type="submit">Submit</button>
</form>
);
}
export default MultipleInputsForm;
React does not provide built-in form validation, but you can easily implement it using state and conditional rendering.
import React, { useState } from 'react';
function ValidatedForm() {
const [formData, setFormData] = useState({
email: '',
password: ''
});
const [errors, setErrors] = useState({
email: '',
password: ''
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value
});
setErrors({
...errors,
[name]: ''
});
};
const validate = () => {
const newErrors = {};
if (!formData.email.includes('@')) {
newErrors.email = 'Invalid email address';
}
if (formData.password.length < 6) {
newErrors.password = 'Password must be at least 6 characters';
}
return newErrors;
};
const handleSubmit = (e) => {
e.preventDefault();
const validationErrors = validate();
if (Object.keys(validationErrors).length > 0) {
setErrors(validationErrors);
} else {
console.log('Form data submitted:', formData);
}
};
return (
<form onSubmit={handleSubmit}>
<label>
Email:
<input type="email" name="email" value={formData.email} onChange={handleChange} />
{errors.email && <span>{errors.email}</span>}
</label>
<br />
<label>
Password:
<input type="password" name="password" value={formData.password} onChange={handleChange} />
{errors.password && <span>{errors.password}</span>}
</label>
<br />
<button type="submit">Submit</button>
</form>
);
}
export default ValidatedForm;
For more complex form handling, you might want to use a third-party library such as Formik or React Hook Form. These libraries provide additional functionality and ease the process of form management, validation, and error handling.
import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
const SignupSchema = Yup.object().shape({
email: Yup.string().email('Invalid email').required('Required'),
password: Yup.string().min(6, 'Too Short!').required('Required')
});
function FormikForm() {
return (
<div>
<h1>Signup</h1>
<Formik
initialValues={{ email: '', password: '' }}
validationSchema={SignupSchema}
onSubmit={(values) => {
console.log('Form data submitted:', values);
}}
>
{({ isSubmitting }) => (
<Form>
<label>
Email:
<Field type="email" name="email" />
<ErrorMessage name="email" component="div" />
</label>
<br />
<label>
Password:
<Field type="password" name="password" />
<ErrorMessage name="password" component="div" />
</label>
<br />
<button type="submit" disabled={isSubmitting}>Submit</button>
</Form>
)}
</Formik>
</div>
);
}
export default FormikForm;
Using these techniques, you can effectively manage forms in React applications.