Consider the following code
const App = () => {
const [errorMsgs, setErrorMsgs] = useState([])
const onButtonPressed = () => {
fetchErrors(setErrorMsgs)
if (!errorMsgs.length) {
// Procced and do somethings
}
}
}
function fetchErrors(setErrorMsgs) {
// if some condition is true:
setErrorMsgs(errorMsgs => [...errorMsgs, "some error"])
// if some other condition is true:
setErrorMsgs(errorMsgs => [...errorMsgs, "some other error"])
}
As far as I understand, when using setErrorMsgs
, it doesn't immediately update the state, and this cannot be solved by using await
or .then()
because setErrorMsgs
doesn't return a promise, therefore, the condition will never be true in this sample.
So what should I do so the condition runs after the state updates? (I don't want the condition to run every time the errorMsgs
changes.)
Edit: To clarify:
The problem, when I call fetchErrors
function, it checks some conditions and might append one, or more errors to errorMsgs
. When I check to see if errorMsgs
is an empty array, the condition will be true even if the fetchErrors
adds anything to the array.
CodePudding user response:
You can't assume that when you change state the variable had it's value changed, but react have a correct way to handle it, by using useEffect, so
const [state, setState] = useState(false)
const onButtonPressed = () => {
setState(true)
}
useEffect(() => {
// here you can do some stuff
},[state])
CodePudding user response:
You can redesign your fetchErrors function, to return the value from the condition, instead of running setter function, then you can do what @RobinZigmond has suggested:
const newErrors = fetchErrors();
setState(newErrors);
if (!newErrors.length) {...}
this way you know for sure what your next state will be like.