I have this react App structure. Some components are hidden based on the content of a local storage.
import React from "react";
import { BrowserRouter as Router } from "react-router-dom";
import AppRoutes from "./Routes";
import NavBar from "./components/NavBar";
const App = () => {
return (
<Router>
<NavBar />
<AppRoutes />
</Router>
);
};
export default App;
All of my other react components are responsive except Navbar. What am I doing wrong? This is my NavBar code:
import { useEffect, useState } from "react";
function NavBar() {
const [role, setRole] = useState("");
useEffect(() => {
setRole(localStorage.getItem("tempUserRole"));
}, []);
return (
<header className="bg-white">
<nav className="" aria-label="Global">
{/* Links (Center-aligned) */}
<div className="">
{role==='a' && <a href="/events" className="">a</a>}
{role==='b' && <a href="/events" className="">EveBnts</a>}
</div>
</nav>
</header>
);
}
export default NavBar;
The problem is, I have to refresh the page to see the changes take effect. How do I solve this issue?
Your useEffect
dependency array is empty, so the hook will only run when the NavBar first renders (or after a refresh, of course).
The naive solution is to just add localStorage.getItem("tempUserRole")
to the dependency array. It will work, but it will throw a warning because React does not want a complex function in the array since that's very expensive to track changes on, unlike a variable.
The more complex solution is to create an event listener on the window and update your state that way. You can bundle that logic in a custom hook. I'll include Maxim's answer here from another question:
You can use custom hooks for that
const profile = useProfileData();
import { useEffect, useState } from "react"; function getProfileData() { return JSON.parse(localStorage.getItem('profile')); } export default function useProfileData() { const [profile, setProfile] = useState(getProfileData()); useEffect(() => { function handleChangeStorage() { setProfile(getProfileData()); } window.addEventListener('storage', handleChangeStorage); return () => window.removeEventListener('storage', handleChangeStorage); }, []); return profile; }
if you don't get why it's not catched see that question Storage event not firing
in summary it's catching events on different pages