Reputation: 1557
So, I'm using hooks to manage the state of a set of forms, set up like so:
const [fieldValues, setFieldValues] = useState({}) // Nothing, at first
When setting the value, the state doesn't update:
const handleSetValues = values => {
const _fieldValues = {
...fieldValues,
...values
}
setFieldValues(_fieldValues)
console.log(fieldValues) // these won't be updated
setTimeout(() => {
console.log(fieldValues) // after ten seconds, it's still not updated
},10000)
}
If I call the function a second time, it'll have updated, but that's not gonna work for me. I never saw behaviour like this in class components.
Is it meant to... like, not update? Or just update whenever it feels like it? Really confusing behaviour.
Upvotes: 0
Views: 372
Reputation: 1602
setFieldValues(_fieldValues)
is an async call, means you won't able to get the result in the very next line of this.
You can use useEffect
hook.
useEffect(() => {
// do your work here
}, [fieldValues]);
It seems from your question that you have background of Class components of React, so useEffect
is similar to componentDidMount
and componentDidUpdate
lifecycle methods.
useEffect
calls whenever the state in the dependency array (in your case [fieldValues]) changes and you get the updated value in useEffect
body.
You can also perform componentWillUnmount
work in useEffect
as well.
Have a brief guide.
Upvotes: 2
Reputation: 19194
setFieldValues
is an asynchronous function, so logging the value below the statement will not have any effect.
Regarding using setTimeout
, the function would capture the current value of props being passed to it and hence that would be the value printed to the console. This is true to any JS function, see the snippet below:
function init(val) {
setTimeout(() => {
console.log(val);
}, 1000);
}
let counterVal = 1;
init(counterVal);
counterVal++;
So how can we print the values when the value changes? The easy mechanism is to use a useEffect
:
useEffect(() => {
console.log(fieldValues)
}, [fieldValues]);
Upvotes: 0