Handling Multiple Inputs
Handling Multiple Inputs
When building a controlled form with multiple inputs, the naïve approach is to create a separate useState Hook and a separate onChange handler for every single input.
// ❌ The Tedious Way
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [email, setEmail] = useState('');
const handleFirstName = (e) => setFirstName(e.target.value);
const handleLastName = (e) => setLastName(e.target.value);
const handleEmail = (e) => setEmail(e.target.value);
For a form with two inputs, this is fine. For a form with ten inputs, this becomes a nightmare to manage.
The Single State Object Pattern
To handle multiple inputs cleanly, you should use a single state object to hold all the form data, and a single, unified handleChange function.
How it works
- Define a single
useStateobject where the keys match thenameattributes of your HTML inputs. - Give every
<input>anameattribute. - Write one
handleChangefunction that uses theevent.target.nameto figure out which part of the state object to update.
import { useState } from 'react';
function MultiInputForm() {
// 1. Single state object
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: ''
});
// 2. Unified change handler
const handleChange = (event) => {
const { name, value } = event.target;
setFormData(prevData => ({
...prevData, // Copy all existing data
[name]: value // Overwrite only the specific field that changed
}));
};
const handleSubmit = (event) => {
event.preventDefault();
console.log("Submitting:", formData);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="firstName" // MUST match the state key
value={formData.firstName}
onChange={handleChange}
/>
<input
type="text"
name="lastName" // MUST match the state key
value={formData.lastName}
onChange={handleChange}
/>
<input
type="email"
name="email" // MUST match the state key
value={formData.email}
onChange={handleChange}
/>
<button type="submit">Submit</button>
</form>
);
}
Handling Checkboxes
Checkboxes are a slight exception. Instead of reading event.target.value, you need to read event.target.checked. You can easily adapt the unified handler to support both text inputs and checkboxes.
const handleChange = (event) => {
const { name, value, type, checked } = event.target;
// Determine the correct value based on the input type
const newValue = type === 'checkbox' ? checked : value;
setFormData(prevData => ({
...prevData,
[name]: newValue
}));
};
Interview Questions
Q: How can you handle 10 different text inputs in a form without writing 10 different state variables and 10 different onChange functions?
A: Store the form data as a single state object. Give every input a name attribute matching the object keys, and use a single dynamic onChange handler:
setFormData(prev => ({ ...prev, [e.target.name]: e.target.value }))