Update:
So I tried to figure it out, but couldn't. I have an onClick that triggers the toggleNavbar
function.
I also have the windowResized
function which checks if the browser is wider than 576. If that condition is true it checks if the navbarState
is true. If both conditions are true the toggleNavbar
function should be called from the windowResized
function.
The issue that I'm having is that the if statement below (the one in the windowResized
function) never runs, because the state doesn't update.
if (navbarState) {
toggleNavbar()
}
Is there a way to make sure that the navbarState updates before I do the checks?
navbar.js
import React, { useState, useRef, useEffect } from "react"
import { Link } from "gatsby"
import styles from "./styling/navbar.module.less"
const Navbar = ( props ) => {
const [navbarState, setNavbarState] = useState(false)
const [navHeight, setNavHeight] = useState()
const ref = useRef(null)
useEffect(() => {
let windowResized = () => {
let windowWidth = window.innerWidth
if (windowWidth > 576) {
if (navbarState) {
toggleNavbar()
}
}
}
window.addEventListener('resize', windowResized)
setNavHeight(ref.current.clientHeight)
}, [])
let toggleNavbar = () => {
setNavbarState((navbarState) => !navbarState)
if (navbarState) {
props.updateClassNames(styles.contentLeftAnimate)
}
else{
props.updateClassNames(styles.contentRightAnimate)
}
}
return (
<nav ref={ref} id={"navigation-bar"}>
<div className={`${styles.navLinks} ${navbarState? styles.navActive:""}`}
style={{top: `${navHeight}px`}}>
{props.pages.map((page, index) => (
<Link key={page.name} className={`${styles.navLink} ${styles.navLinkHoverEffect} ${navbarState? styles.navAnimate:""}`}
style={{animationDelay: `${index / 7 + 0.5}s`}} to={page.link}>
{page.name}
</Link>
))}
</div>
<div className={`${styles.burger} ${navbarState? styles.toggle:""}`} onClick={toggleNavbar}>
<div className={styles.line1}></div>
<div className={styles.line2}></div>
<div className={styles.line3}></div>
</div>
</nav>
)
}
export default Navbar
You never set navbarState to false again, also put adding event listeners in an effect is better so try this instead:
//only set the event listener on mount
useEffect(() => {
let windowResized = () => {
let windowWidth = window.innerWidth;
if (windowWidth > 576) {
// if (navbarState) { this was a stale closure
setNavbarState(false);
console.log('Toggle navbar - Width > 576');
} else {//not sure if you need this else
console.log('Window is bigger than mobile');
//set it to true again when it goes over 576 (not sure if you need this)
setNavbarState(true);
}
};
window.addEventListener('resize', windowResized);
//probably never happens to layout but if unmounted
// remove the event listener
return () =>
window.removeEventListener('resize', windowResized);
}, []);
The toggle is probably wrong as well if you expect navbarState to immediately change after calling setNavbarState, instead try this
setNavbarState((navbarState) => {
const newState = !navbarState;
if (newState) {
props.updateClassNames(styles.contentLeftAnimate);
} else {
props.updateClassNames(styles.contentRightAnimate);
}
return newState;
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.