skip to Main Content

I display different Nav paths depending on the type of user that is logged in.

Some code:

const celeb = localStorage.getItem("celeb");
const [navPath, setNavPath] = useState("");
useEffect(() => {
    const path = celeb == "true" ? "dashboard" : "requests";

    setNavPath(path);
}, []);

the celeb returned from above is either "true" or "false" (string btw).

in the useEffect, I set the navPath to "dashboard" if the celeb is true, and if the celeb is not true I set the navPath to ‘requests’.

here is my navigation stats:

const [navigation, setNavigation] = useState([
    { name: "Catogories", href: "#", current: false },
    { name: "Home", href: "#", current: false },
    { name: "How does it work", href: "#", current: false },
    { name: "Celebs", href: "#", current: false },
    { name: "About", href: "#", current: false },
    { name: navPath, href: navPath, current: false },
 ]);

On first Render the navPath logs empty, but on the second it logs either request or dashboard. The problem is that when the navPath is set to a new value, it doesn’t cause a render, so I have reload to see the changes.

Why is that?

2

Answers


  1. The useEffect hook in your code is not causing a re-render because it only runs once after the initial rendering of the component due to its dependency array being empty ([]). This means it will not respond to changes in celeb because celeb is not included in the dependency array.
    To solve this issue, you could move the fetching of celeb into the useEffect hook and include celeb in the dependency array. However, because localStorage is not reactive, changes to it won’t trigger a re-render of the component. Instead, you could listen for changes to localStorage using an event listener. Here’s an example

    useEffect(() => {
     function checkCelebData() {
       const celeb = localStorage.getItem('celeb');
    
       if (celeb) {
         const path = celeb == "true" ? "dashboard" : "requests";
         setNavPath(path);
       }
     }
    
     window.addEventListener('storage', checkCelebData);
    
     return () => {
       window.removeEventListener('storage', checkCelebData);
     }
    }, []);
    
    Login or Signup to reply.
  2. You need another useEffect to update navigation.

    useEffect(() => setNavigation([...defaultNavigation, { name: navPath, href: navPath, current: false }]), [navPath]);
    

    Full code

    const App = () => {
      const celeb = localStorage.getItem("celeb");
      const defaultNavigation = [
        { name: "Catogories", href: "#", current: false },
        { name: "Home", href: "#", current: false },
        { name: "How does it work", href: "#", current: false },
        { name: "Celebs", href: "#", current: false },
        { name: "About", href: "#", current: false },
      ];
      const [navPath, setNavPath] = useState("");
      const [navigation, setNavigation] = useState([...defaultNavigation, { name: navPath, href: navPath, current: false }]);
      useEffect(() => {
        const path = celeb == "true" ? "dashboard" : "requests";
        setNavPath(path);
      }, []);
      useEffect(() => setNavigation([...defaultNavigation, { name: navPath, href: navPath, current: false }]), [navPath]);
      return navigation.map(({ name, href, current }) => (
        ...
      ));
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search