'Storing React form data in a nested object with useState
I'm building out a form with React, and I want to store the form fields in an object with nested data like this:
{
name: "Test User",
email: "[email protected]",
address: {
street: "123 Main St",
city: "New York",
state: "NY"
}
}
The nested address
is what I'm having trouble with.
My code looks like this:
const [booking, setBooking] = React.useState({ address: {} });
const handleChange = e => {
const { name, value } = e.target;
setBooking(prevState => ({
...prevState,
[name]: value
}));
};
return (
<form onSubmit={handleSubmit}>
<label>Name</label><input type="text" name="name" value={booking.name} onChange={handleChange} />
<label>Email</label><input type="text" name="email" value={booking.email} onChange={handleChange} />
<label>Street Address</label><input type="text" name="address.street" value={booking.address.street} onChange={handleChange} />
<label>City</label><input type="text" name="address.city" value={booking.address.city} onChange={handleChange} />
<label>State</label><input type="text" name="address.state" value={booking.address.state} onChange={handleChange} />
<button type="submit">Create booking</button><br /><br />
</form>
)
But with this approach, the address values are not being nested. For example, for the street address field, the booking
ends up with a key of address.street
rather than using the nested address
object.
How can I get the form data to be stored in a nested object?
Solution 1:[1]
you need to create two onchange events function one for booking and another for address
const [booking, setBooking] = React.useState([]);
const [addressDetails, setAddressDetails] = useState([])
function handleChange(e) {
setBooking(prevState => ({
...prevState,
...prevState.raw,
[e.target.name]: e.target.value,}
))
}
function handleChangeAddress(e) {
setAddressDetails(prevState => ({
...prevState,
Address: {
...prevState.Address,
[e.target.name]: e.target.value,
},
}))
setBooking(prevState => ({
...prevState,
...prevState.store,
Address:addressDetails.Address
}))
}
Solution 2:[2]
For the address you can create a separate handler function, i'm using typescript to explain but you can do the same in Javascript too( just remove types of e from function parameter)
const onAddressHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
setBooking({
...booking,
address:{
...booking.address,
[e.target.name]: e.target.value
},
});
};
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Nivethan |