Skip to content

My React state doesn’t update when setState is called

I’m trying to make a simple animation when the burger element is clicked

I’m trying to update the following state with an animation when the burger is clicked but the state doesn’t update no matter what i try.

 import React from 'react'
import {useEffect, useRef, useState} from 'react';



const Navbar = () => {

  const [animations, setAnimations] = useState({
      style1:{animation:null},
      style2:{animation:null},
      style3:{animation:null},
      style4:{animation:null}
  }) 


  let burger = useRef(null)
  let nav = useRef(null)
  function HandleBurger(){
        nav.classList.toggle('nav-active');
        Object.keys(animations).forEach((link, index) => {
            if (animations[link].animation) {
              setAnimations(prevState =>{
                return  {...prevState,  animation: ''}
              });
            } else {

                  setAnimations(prevState =>{
                    return  {link: {animation: `navLinkFade 0.5s ease forwards ${index / 7 + 1}s`}}
                  });
                  console.log(animations);
            }            
          })          
          burger.classList.toggle('toggle') 
 }
  
  return (
        <nav className="navbar">
            <div className="logo">
                <h3 id="art">BURJTECH</h3>
                <h3 id="scope">LIMITED</h3>
            </div>
            <div className="side-header" ref={el=>nav=el}>
                <li style={animations["style1"]}><a className="cool-link" href="/">Homepage</a></li>
                <li style={animations["style2"]}><a className="cool-link" href="/about">About</a></li>
                <li style={animations["style3"]}><a className="cool-link" href="/services">Services</a></li>
                <li style={animations["style4"]}><a className="cool-link" href="/contact">Contact</a></li>
            </div>
            <div className="burger" ref={el=>burger=el} onClick={HandleBurger}>
                <div className="line1"></div>
                <div className="line2"></div>
                <div className="line3"></div>
            </div>
        </nav>
  )
}

Edit: Someone suggested i post the full code

Answer

There’s a lot of bad smells going on in your code. The first improvement that can be made is for you to use a single setState call instead of calling it in a loop:

function HandleBurger() {
 //...

 setAnimations(state => {
    return Object.keys(state).reduce((acc,key,index) => {
      if(state[key].animation) return {...acc,[key]:animation:null};
      return {...acc,[key]:animation: `navLinkFade ....`}
    },state);
 });

 //...
}

You also should not being using refs to toggle class names, that’s not the react way of doing things. I’d really like to see the rest of you component.

Post it.