Forms in React: Controlled vs. Uncontrolled Components
Introduction to Forms in React
Forms are essential for user input in web applications. In React, form handling can be done using two approaches:
- Controlled Components: React handles the form data through state.
- Uncontrolled Components: The DOM directly manages the form data.
Controlled Components
In controlled components, form inputs are bound to React state. This approach ensures React is the single source of truth for form data.
How It Works
- Input values are set using
value
attributes tied to state. - Changes are handled using
onChange
events to update the state.
Example: Controlled Component
import React, { useState } from 'react';
function ControlledForm() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
console.log(`Name: ${name}, Email: ${email}`);
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>
Name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
</div>
<div>
<label>
Email:
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</label>
</div>
<button type="submit">Submit</button>
</form>
);
}
export default ControlledForm;
Uncontrolled Components
In uncontrolled components, form inputs are not bound to state. Instead, refs are used to access DOM elements directly.
How It Works
- The
ref
attribute is used to reference input fields. - Values are retrieved using
ref.current.value
.
Example: Uncontrolled Component
import React, { useRef } from 'react';
function UncontrolledForm() {
const nameRef = useRef();
const emailRef = useRef();
const handleSubmit = (e) => {
e.preventDefault();
console.log(`Name: ${nameRef.current.value}, Email: ${emailRef.current.value}`);
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>
Name:
<input type="text" ref={nameRef} />
</label>
</div>
<div>
<label>
Email:
<input type="email" ref={emailRef} />
</label>
</div>
<button type="submit">Submit</button>
</form>
);
}
export default UncontrolledForm;
Controlled vs. Uncontrolled Components
Feature | Controlled Components | Uncontrolled Components |
---|---|---|
Data Handling | Managed via React state. | Managed directly by the DOM. |
Access to Data | Data is always up-to-date in state. | Use ref to access current values. |
Use Case | Preferred for dynamic, interactive forms. | Simple forms or legacy code. |
Performance | Can be slower for large forms. | Can be faster for simple forms. |
Handling Form Submissions in React
Handling form submissions involves:
- Preventing the default form behavior using
e.preventDefault()
. - Accessing and validating the form data.
- Submitting the data (e.g., via an API).
Example: Form Submission
import React, { useState } from 'react';
function FormWithSubmission() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
const formData = { name, email };
try {
const response = await fetch('/api/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData),
});
if (response.ok) {
alert('Form submitted successfully!');
} else {
alert('Failed to submit form.');
}
} catch (error) {
console.error('Error:', error);
}
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>
Name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
</div>
<div>
<label>
Email:
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</label>
</div>
<button type="submit">Submit</button>
</form>
);
}
export default FormWithSubmission;
Best Practices for React Forms
- Prefer Controlled Components: For consistency and better validation.
- Validate Inputs: Use libraries like
Yup
orFormik
for form validation. - Avoid Inline State Management: Use custom hooks for better code organization in large forms.
- Optimize Performance: Avoid unnecessary re-renders using React.memo or other optimization techniques.
- Use Libraries for Complex Forms: Libraries like Formik or React Hook Form simplify form handling.