React button onClick requires two click to work second time

Viewed 735

When the img is pressed the side menu opens fine but when i close the side menu and try to open it again by pressing the img it requires two clicks to open. how do i make it so it works with one click even after i open and close the side menu?

const Header = () => {
  let [isOpen, setIsOpen] = useState(false);
  return (
    <header className='homepage-header'>
        <img src={menusvg} alt='' onClick={() => setIsOpen((isOpen) => !isOpen)} />
        {
            isOpen ? <SideMenu /> : null
        }
        <h1>Main Header</h1>
    </header>
  )
}

note: i have another button inside the SideMenu componenet that closes the menu.

SideMenu:

function SideMenu() {
  let [isOpen, setIsOpen] = useState(true);
  return (
    <>
        {
            isOpen ? <div className='side-menu'>
                <p>side menue</p>
                <i class="fas fa-times" onClick={() => setIsOpen((isOpen) => !isOpen)}></i>
            </div>
                : null
        }
    </>
  )
}
2 Answers

You are using two different states, pass isOpen and setIsOpen as props to SideMenu

Try this code

function SideMenu({ isOpen, setIsOpen }) {
  return (
    <>
      {isOpen ? (
        <div className="side-menu">
          <p>side menue</p>
          <button onClick={() => setIsOpen(isOpen => !isOpen)}>Close</button>
        </div>
      ) : null}
    </>
  );
}

--

export default function App() {
  let [isOpen, setIsOpen] = React.useState(false);
  return (
      <header className="homepage-header">
        <img
          src={'https://picsum.photos/200'}
          alt=""
          onClick={() => setIsOpen(isOpen => !isOpen)}
        />
        {isOpen ? <SideMenu isOpen={isOpen} setIsOpen={setIsOpen} /> : null}
        <h1>Main Header</h1>
      </header>
  );
}

Sample Code: https://stackblitz.com/edit/react-j4rxot?file=src%2FApp.js

The logic you have used to make isOpen true and false is bit wierd,(at least for me), although feels correct.

A simple way would be,

const Header = () => {
  let [isOpen, setIsOpen] = useState(false);
  return (
    <header className='homepage-header'>
        <img src={menusvg} alt='' onClick={() => isOpen ? setIsOpen(false) : setIsOpen(true)} />
        {
            isOpen ? <SideMenu /> : null
        }
        <h1>Main Header</h1>
    </header>
  )
}

Hope it works!
Related