Search code examples
cssreactjsnavbarmaterialize

Materialize navbar links conditional rendering


I am using React Materialize and React Router Dom. I'm trying to show navlinks to only authenticated users, so I'm using conditional rendering. But if I do it like below, navlinks are rendered vertical, not horizontal as usual. Is there a solution for that? Thanks

    <Navbar>
      {isAuthenticated && (
      <>
      <NavLink to="/locations" href="/locations">
        Locations
      </NavLink>
      <NavLink to="/categories" href="/categories">
        Categories
      </NavLink>
      </>
      )}
    </Navbar>

Solution

  • Looks like the Navbar component is rendering all of its children inside li elements. When you wrap them in a fragment, the component considers this as its only child element and puts all of the NavLink elements in a single li.

    I can think of two simple approaches to handle this:

    1. If there are only a few links, you can do conditional rendering for them:
    <Navbar>
     {isAuthenticated && (<NavLink to="/locations" href="/locations">Locations</NavLink>)}
     {isAuthenticated && (<NavLink to="/categories" href="/categories">Categories</NavLink>)}
    </Navbar>
    

    However, this solution is not reliable, especially if you have a lot of links.

    1. Store the NavLink elements in some array and conditionally add the auth-dependant items:
    // In the component:
    const links = [/* some public links */];
    const privateLinks = [
        // Don't forget keys. The numbers here are only for example.
        <NavLink key={1} to="/locations" href="/locations">Locations</NavLink>,
        <NavLink key={2} to="/categories" href="/categories">Categories</NavLink>
    ];
    
    if(isAuthenticated){
     links.push(...privateLinks);
    }
    
    // In the template:
    <Navbar>{links}</Navbar>
    

    The logic with the links arrays is pretty trivial (with setting private links as the last items) only to keep the demo more simple.