My goal is to dynamically show or hide links based on user authorization. Here's my initial approach:
const Navbar = () => {
const { canDo, ...} = useUser(); //A Zustand store
return (
<>
<div>
<ul>
{canDo && (
<li>
<Link href="/somelink">Something</Link>
</li>
)} ...//more options
Upon screen load or refresh, I encountered this error:
Error: Hydration failed because the initial UI does not match what was rendered on the server.
Warning: Expected server HTML to contain a matching "li" in "ul".
For my second attempt, I used useEffect:
const Navbar = () => {
const Navbar = () => {
const { canDo, ...} = useUser(); //A Zustand store
var doit = false;
useEffect(() => {
doit = canDo;
}, [canDo, ...]);
<ul>
{doit && (
<li>
<Link href="/somelink">Something</Link>
</li>
Unfortunately, this method did not cause the navbar to refresh.
As a last resort, I attempted to render different menus based on conditions, but this also led to the hydration error upon refresh.
The root of the issue lies with the Zustand store - it gets cleared and reloaded on browser refresh, causing React to render differently on the server compared to the client side.
Despite best practices, I resorted to manipulating the display style attributes of the "li" elements within the useEffect. I am aware that this approach goes against traditional React principles.