Search code examples
reactjsreact-hookssetstate

React useState with a callback


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()
}
}

Solution

  • 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) 
    }
    }