I'm writing a function that simultaneously sets state AND assigns it to an object.. I'm specifically talking about setValue
and after: value
const handleAddToHistory = (e) => {
e.preventDefault();
setValue((parseFloat(Object.values(data))*fromTo).toFixed(2))
setHistory([ ... history , {
date: new Date().toISOString().slice(0, 10),
before: fromTo,
after: value,
}])
}
However, on the first run "value" is empty. It forces me to click the button again, and only then it shows all the data properly.
How can I setState and immiediately invoke it ? Should I do some sort of Time Interval on setHistory to wait until setValue is actually set?
CodePudding user response:
When you set state in React, it's asynchronous, since it triggers a re-render. Therefore, you use useEffect
to handle anything that needs to happen when value
changes:
useEffect(() => {
setHistory([ ... history , {
date: new Date().toISOString().slice(0, 10),
before: fromTo,
after: value,
}])
}, [value])
CodePudding user response:
Any reason to not do this?
const handleAddToHistory = (e) => {
e.preventDefault();
const valueToSave = (parseFloat(Object.values(data))*fromTo).toFixed(2);
setValue(valueToSave)
setHistory([ ... history , {
date: new Date().toISOString().slice(0, 10),
before: fromTo,
after: valueToSave,
}])
}
If that doesn't work for some reason, you can use a useEffect
hook:
const handleAddToHistory = (e) => {
e.preventDefault();
setValue(parseFloat(Object.values(data))*fromTo).toFixed(2))
}
useEffect(() => {
setHistory([ ... history , {
date: new Date().toISOString().slice(0, 10),
before: fromTo,
after: value,
}]);
}, [value]);