I'm aware that useState is asynchronous. I'm attempting to have a toggle button that will add one point to score
if itemSelected
is true and remove one point from score
if itemSelected
is false. The issue here of course is that due to the asynchronous nature of setState there is a delay so the code below doesn't work properly.
My question: How do I get around this issue?
const [score, setScore] = useState(0);
const [itemSelected, setItemSelected] = useState(false);
const toggleItem1 = () => {
setItemSelected(!itemSelected, setCallback())
}
const setCallback = () => {
if (score < 5 && itemSelected ){
setScore(score + 1)
}
if (score < 5 && !itemSelected ){
setScore(score - 1)
}
if (score == 5){
completeSection()
}
}
The real issue is that you are trying everything in one function. You are mutating the state and reading it in the same place.
I would put a controller, like useEffect
, useCallback
or useMemo
to read the state, and if it satisfies a condition, it would trigger a function, like this:
const [score, setScore] = useState(0);
const [itemSelected, setItemSelected] = useState(false);
useEffect(()=>{
if(score === 5){
completeSection()}
}
,[score])
const toggleItem1 = () => {
setItemSelected(!itemSelected, setCallback())
}
const setCallback = () => {
if (score < 5 && itemSelected ){
setScore(score + 1)
}
if (score < 5 && !itemSelected ){
setScore(score - 1)
}
}