The component
I had a React WebApp that used this Navbar Component for every page:
import React, { useState, useEffect } from "react";
...
function useMobileView() {
const [isMobile, setIsMobile] = useState(window.innerWidth < 768);
useEffect(() => {
setIsMobile(window.innerWidth < 768);
const handleResize = () => {
setIsMobile(window.innerWidth < 768);
};
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return isMobile;
}
export default function SMNavbar(active) {
const isMobile = useMobileView();
return (
<Navbar>
<NavbarBrand>
<a
href="/"
>
<img
src="Logo.png"
alt="logo"
/>
</a>
</NavbarBrand>
{!isMobile ? (
<React.Fragment>
<NavbarContent>
...Navbar Items
</NavbarContent>
</React.Fragment>
) : (
<React.Fragment>
<NavbarMenuToggle />
<NavbarMenu>
{/* Explicitly defining each NavbarMenuItem for mobile view */}
...Navbar Items
</NavbarMenu>
</React.Fragment>
)}
</Navbar>
);
}
This worked fine when using React, because everything is loaded once it reaches the client anyway. So it was able to access the ‘window’ attribute and differenciate between the mobile and desktop navbars.
The problem
Now however I’m trying to make a similair webapp using NextJS and want to use my Navbar component again. The problem is that even when I use ‘use client’ it still does some partial server-side rendering. It doesn’t recognize the ‘window’ attribute when doing this so I have to use
if (typeof window === "undefined") return;
but that’s besides the point really. Basically, because the whole rendering is based on the outcome of window.innerWidth < 768
to decide if it should render the mobile navbar or the desktop one, the only two options I see are this:
- Initially set the result of isMobile to either true or false
This is a disgusting solution for me, because it will hop from the initial state to the proper one for every page load if its not initially set correctly.
- Import the Navbar like this for every component that uses it:
const Navbar = dynamic(() => import("../components/Navbar"), {
ssr: false,
});
I don’t like this at all either, because then while the page has already basically loaded, the Navbar is nowhere to be found. It takes about a full second for it to show up.
I am still kind of new to Frontend Frameworks, so if there is an obvious solution and I haven’t found it I would be delighted.
I mean, big corperations with their websites must be facing/have long solved the issue of this?
Any help would be GREATLY appreciated.