skip to Main Content

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?

2

Answers


  1. 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

    Login or Signup to reply.
  2. Can you see if at all there is any thing being stored in local storage in the first place?

    import { useEffect, useState } from "react";
    
    function NavBar() {
    const [role, setRole] = useState(null);
    
    useEffect(() => {
    const storedRole = localStorage.getItem("tempUserRole");
    if (storedRole) {
      setRole(storedRole);
    } else {
      setRole("");
    }
    }, []);
    
    return (
    <header className="bg-white">
      <nav aria-label="Global">
        {/* Links (Center-aligned) */}
        <div>
          {role === 'a' && <a href="/events" className="">a</a>}
          {role === 'b' && <a href="/events" className="">EveBnts</a>}
        </div>
      </nav>
     </header>
     );
     }
    
    export default NavBar;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search