In the project i am working on, I am trying to implement a Hamburger Menu functionality using React. I decided to toggle a boolean (useHamburger) using the function TurnToHamburger. These would change the stylesheet of the navbar so that it would look like a dropdown menu. Problem is, it would only toggle once and after that the appearance of the navbar does not change at all. How do i solve this?
Below is the relevant code.
import {useState} from 'react'
const Navbar = ({img}) => {
const navbarinitial = {
listStyle: 'none',
display: 'flex',
justifyContent: 'space-around',
flexDirection:'row',
width: '30%',
color: 'var(--GrayishViolet)'
};
const navbarfinal = {
listStyle: 'none',
display: 'flex',
flexDirection:'column',
justifyContent: 'space-around',
width: '30%',
color: 'var(--GrayishViolet)',
backgroundColor:'red'
}
let useHamburger = false;
const [navbarstyle, setNavbarStyle] = useState(navbarinitial);
const TurnToHamburger=()=> {
if (!useHamburger) {
setNavbarStyle(navbarfinal)
useHamburger = true;
}
else {
setNavbarStyle(navbarinitial)
useHamburger = false;
}
}
In the useState() hold the current status of the menu (hamburger). The state should be a Boolean - hamburger open or not. Toggle this state to change the menu. The selection of the style object should be derived from the current value of the hamburger state.
const { useState } = React;
const navbarinitial = {
listStyle: "none",
display: "flex",
justifyContent: "space-around",
flexDirection: "row",
width: "30%",
color: "var(--GrayishViolet)",
};
const navbarfinal = {
listStyle: "none",
display: "flex",
flexDirection: "column",
justifyContent: "space-around",
width: "30%",
color: "var(--GrayishViolet)",
backgroundColor: "red",
};
const Navbar = () => {
const [hamburger, setHamburger] = useState(false);
const toggleHamburger = () => setHamburger((prev) => !prev);
return (
<nav>
<div className="nav-right">
<ul
className="nav-options"
style={hamburger ? navbarfinal : navbarinitial}
>
<li>Features</li>
<li>Pricing</li>
<li>Resources</li>
</ul>
<div className="navbar-buttons">
<button onClick={toggleHamburger}>Toggle Burger</button>
</div>
</div>
</nav>
);
};
ReactDOM.render(<Navbar />, root);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>
The reason why it doesn't work is because any variable that doesn't use useState will be reset each time the component renders. Do this instead:
const [hamburger_open, setHamburgerOpen] = useState(false);
const TurnToHamburger=()=> {
if (!hamburger_open) {
setNavbarStyle(navbarfinal);
setHamburgerOpen(true);
} else {
setNavbarStyle(navbarinitial);
setHamburgerOpen(false);
}
}
const toggleHamburger = () => setHamburger(!prev);