The React useState Hook allows us to track state in a function component. State generally refers to data or properties that need to be tracking in an application.
Unlike the setState method found in class components, useState does not automatically merge update objects.
useState is a Hook that allows you to have state variables in functional components. You pass the initial state to this function and it returns a variable with the current state value (not necessarily the initial state) and another function to update this value.
useState, the default value will never change, because useState only called once, even the num props changed, the state will never change. Now with useEffect monitor on num props, the child component will get correct value from state. It is common mistake usually happened to new React developer.
You can pass new value like this:
setExampleState({...exampleState, masterField2: {
fieldOne: "a",
fieldTwo: {
fieldTwoOne: "b",
fieldTwoTwo: "c"
}
},
})
If anyone is searching for useState() hooks update for object
- Through Input
const [state, setState] = useState({ fName: "", lName: "" });
const handleChange = e => {
const { name, value } = e.target;
setState(prevState => ({
...prevState,
[name]: value
}));
};
<input
value={state.fName}
type="text"
onChange={handleChange}
name="fName"
/>
<input
value={state.lName}
type="text"
onChange={handleChange}
name="lName"
/>
***************************
- Through onSubmit or button click
setState(prevState => ({
...prevState,
fName: 'your updated value here'
}));
Generally you should watch out for deeply nested objects in React state. To avoid unexpected behavior, the state should be updated immutably. When you have deep objects, you end up deep cloning them for immutability, which can be quite expensive in React. Why?
Once you deep clone the state, React will recalculate and re-render everything that depends on the variables, even though they haven't changed!
So, before trying to solve your issue, think how you can flatten the state first. As soon as you do that, you will find handy tools that will help dealing with large states, such as useReducer().
In case you thought about it, but are still convinced you need to use a deeply nested state tree, you can still use useState() with libraries like immutable.js and Immutability-helper. They make it simple to update or clone deep objects without having to worry about mutability.
I'm late to the party.. :)
@aseferov answer works very well when the intention is to re-enter the entire object structure. However, if the target/goal is to update a specific field value in an Object, I believe the approach below is better.
situation:
const [infoData, setInfoData] = useState({
major: {
name: "John Doe",
age: "24",
sex: "M",
},
minor:{
id: 4,
collegeRegion: "south",
}
});
Updating a specific record will require making a recall to the previous State prevState
Here:
setInfoData((prevState) => ({
...prevState,
major: {
...prevState.major,
name: "Tan Long",
}
}));
perhaps
setInfoData((prevState) => ({
...prevState,
major: {
...prevState.major,
name: "Tan Long",
},
minor: {
...prevState.minor,
collegeRegion: "northEast"
}));
I hope this helps anyone trying to solve a similar problem.
Thanks Philip this helped me - my use case was I had a form with lot of input fields so I maintained initial state as object and I was not able to update the object state.The above post helped me :)
const [projectGroupDetails, setProjectGroupDetails] = useState({
"projectGroupId": "",
"projectGroup": "DDD",
"project-id": "",
"appd-ui": "",
"appd-node": ""
});
const inputGroupChangeHandler = (event) => {
setProjectGroupDetails((prevState) => ({
...prevState,
[event.target.id]: event.target.value
}));
}
<Input
id="projectGroupId"
labelText="Project Group Id"
value={projectGroupDetails.projectGroupId}
onChange={inputGroupChangeHandler}
/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With