I am trying to create a responsive nav. It has a _ functions:
I got 99% of this accomplished, but I think I'm doing it in a hacky way because when I am on smaller screens, the nav links flash for a brief moment, then dissapear. This is obviously not what I am looking for.
Below is a condensed, not styled snippet for easier debugging:
export const Nav = () => {
const [showNavOnClick, setShowNavOnClick] = useState(false)
const [hamburgerOpen, setHamburgerOpen] = useState(false)
const [showNavOnScreenSize, setShowNavOnScreenSize] = useState(true)
const toggleMenu = () => {
setShowNavOnClick(!showNavOnClick)
setHamburgerOpen(!hamburgerOpen)
}
useEffect(() => {
// This line solves all 3 goals, but on page load, the nav links appear, then dissapear in a split moment.
if (window.innerWidth < 768) setShowNavOnScreenSize(false)
const handleResize = () => {
if (window.innerWidth > 768) {
setShowNavOnScreenSize(true)
setShowNavOnClick(false)
} else if (window.innerWidth < 768) {
setShowNavOnScreenSize(false)
}
}
window.addEventListener('resize', handleResize)
return () => {
window.removeEventListener('resize', handleResize)
}
}, [])
return (
<nav>
<a href="/">Home</a>
<button onClick={toggleMenu}>*</button>
<a
href="/about"
className={`${
showNavOnScreenSize ||
showNavOnClick && showNavOnScreenSize != showNavOnClick)
? 'visible'
: 'hidden'
}`}>
About
</a>
</nav>
)
}
Below is a video that shows the glitch:
When I add const [showNavOnScreenSize, setShowNavOnScreenSize] = useState(window.innerWidth >= 768)
, I get an error of window is not defined
You can fix this by changing the default value of the state to be calculated from the width, instead of a hardcoded true
:
const [showNavOnScreenSize, setShowNavOnScreenSize] = useState(window.innerWidth >= 768)
If necessary, you can set the default values for your other states in a similar way.
EDIT: Alternatively, try using a layout effect instead so that the rerender is synchronous:
const [showNavOnScreenSize, setShowNavOnScreenSize] = useState(true)
useLayoutEffect(() => {
if (window.innerWidth < 768) setShowNavOnScreenSize(false)
// ...
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.