Home > Blockchain >  Update state value within a setInterval not working
Update state value within a setInterval not working

Time:02-19

when I click a btn, cycleColor is called and counter starts, at Na=1 we set the element color to red which works at it should. At Nb=2 we set the color to yellow and finally at Nc = 3 we set it to green.

After the color has been set, I want to set the Nth corresponding value to be equal to the current value 3 (n 3):

enter image description here

    const [color, setColor] = useState(null)
    const [Na, setNa] = useState(1)
    const [Nb, setNb] = useState(2)
    const [Nc, setNc] = useState(3)
    
    const cycleColor = () =>{
        let counter = 0

        setInterval(()=>{
            // if(color == null){
            //     console.log('color is null');
            //     setColor('red')
            // }else if(color == 'red'){
            //     console.log('color is red');
            //     setColor(()=>{return 'yellow'})
            // }else if(color == 'yellow'){
            //     console.log('color is yellow');
            //     setColor(()=>{return 'green'})
            // }
            counter  
            if(counter == Na){
                setColor('red')
                console.log(Na);
                setNa(prevState => prevState 3)
            }else if(counter == Nb){
                setColor('yellow')
                console.log(Nb);
                setNb(prevState => prevState 3)
            }else if(counter == Nc){
                setColor('green')
                console.log(Nc);
                setNc(prevState => prevState 3)
            }

            console.log(counter, Na, Nb, Nc);
            // console.log("Color === null: "   (color === null));
            // console.log("Color === red: "   (color === 'red'));
            // console.log("Color === yellow: "   (color === 'yellow'));
        },1000)
    }

As you can see in the following video, it works fine the first 3 seconds but state of the Nth value does NOT get updated.

https://imgur.com/a/AhMAExO

CodePudding user response:

I think it might be easier to do something like:

counter  
  if(counter % 3 == 1){
    setColor('red')
  }else if(counter % 3 == 2){
    setColor('yellow')
  }else if(counter % 3 == 0){
    setColor('green')
  }

CodePudding user response:

I suspect the values of Na, Nb, and Nc are being captured within your setInterval() method. Look into Javascript Closures.

You should pursue this solution (as a learning exercise), but once you get it to work - consider rewriting differently. e.g. use the mod operator counter % 3 to count 0, 1, 2, 0, 1, 2, ...

update: Also note - the setNa() will not update the value of Na immediately. It updates after the next render. So, if you call setNa(10) and then log Na on the next line, it will still show the old value. Also - closures explain why your counter continues to increment even though you're not saving it using a [counter, setCounter] = useState()...

  • Related