Reputation: 7003
I have the following setup:
this.state = {
values: {
id: null,
name: "",
unitName: "",
unitCategory: ""
}
};
and when I change a value in a field in a form I have the following handleChange
function:
this.setState({
values: {
[e.target.name]: e.target.value
}
});
the problem is - this removes all other values from the values
object in my state and only leaves the one that's being modified (i.e. <input name="name" />
).
How could I retain all other values?
Edit The code now looks like:
this.setState(prevState => {
console.log(prevState.values);
return {
values: {
...prevState.values,
[e.target.name]: e.target.value
}
};
});
The console.log(prevState.values)
returns:
{id: 2, name: "Humidity", unitName: "himidity", unitCategory: "%"}
Which is how it should be, but when I spread it in values
object, I get:
TypeError: Cannot read property 'name' of null
Upvotes: 1
Views: 2425
Reputation: 57964
Use spread syntax to spread the other properties into state:
this.setState(prevState => ({
values: {
...prevState.values,
[e.target.name]: e.target.value
}
}));
This also utilizes the callback with setState
to ensure the previous state is correctly used. If your project doesn't support object spread syntax yet, you could use Object.assign
:
values: Object.assign({}, prevState.values, {
[e.target.name]: [e.target.value]
})
This does essentially the same thing. It starts with an empty object to avoid mutation, and copies prevState.values
's keys and values into the object, then copies the key [e.target.name]
and its value into the object, overwriting the old key and value pair.
Also, I'm not sure why you're doing all this:
this.state = {
values: {
id: this.state.values.id ? this.state.values.id : null,
name: this.state.values.name ? this.state.values.name : "",
unitName: this.state.values.unitName ? this.state.values.unitName : "",
unitCategory: this.state.values.unitCategory? this.state.values.unitCategory: "
}
};
When you set initial state in the constructor, just give the initial value, your ternary operator will never give you the true condition:
this.state = {
values: {
id: null,
name: '',
unitName: '',
unitCategory: ''
}
};
Upvotes: 5