Search code examples
javascriptreactjsreact-routerreact-bootstrapjotai

Nav Menu Active Element and State Management Issue


I am trying to show an active <Nav.Link> element for the current page, but it keeps getting reset when I go between pages to the default value. Each of the links goes to a different route I have defined in React-Router. I am trying to use jotai for state management to store the value of the current page, but am not able to get the correct value to display.

For example, the code below has pills to show the active selection in the nav. I want to be able to do this even when I go to a different page since this is the nav menu.

import Nav from 'react-bootstrap/Nav';

function TabsExample() {
  return (
    <Nav variant="pills" defaultActiveKey="/home">
      <Nav.Item>
        <Nav.Link href="/home">Active</Nav.Link>
      </Nav.Item>
      <Nav.Item>
        <Nav.Link eventKey="link-1">Option 2</Nav.Link>
      </Nav.Item>
      <Nav.Item>
        <Nav.Link eventKey="disabled" disabled>
          Disabled
        </Nav.Link>
      </Nav.Item>
    </Nav>
  );
}

export default TabsExample;

However, I believe my page keeps re-rendering/reloading (goes white for a brief second) for some reason whenever I go to a different page.

There might be something I'm not getting, so please let me know.


Solution

  • The issue here is likely that the Nav.Link component renders an anchor <a> element by default and this is causing the page to reload when you click the links. You can specify each Nav.Link to render the NavLink (or Link) component exported from react-router-dom so that clicking links will now correctly be handled by RRD. Specify a to prop instead of an href prop, and set the eventKey prop to match the link target so the "pill" state can work as well.

    Example:

    import { NavLink } from "react-router-dom";
    import "bootstrap/dist/css/bootstrap.min.css";
    import Nav from "react-bootstrap/Nav";
    
    function PillsExample() {
      return (
        <Nav variant="pills">
          <Nav.Item>
            <Nav.Link as={NavLink} end to="/" eventKey="/"> // * Note on end prop
              Home
            </Nav.Link>
          </Nav.Item>
          <Nav.Item>
            <Nav.Link as={NavLink} to="/foo" eventKey="/foo">
              Foo
            </Nav.Link>
          </Nav.Item>
          <Nav.Item>
            <Nav.Link as={NavLink} to="/bar" eventKey="/bar">
              Bar
            </Nav.Link>
          </Nav.Item>
        </Nav>
      );
    }
    

    Edit nav-menu-active-element-and-state-management-issue

    enter image description here enter image description here enter image description here

    * Note: If the end prop is used, it will ensure this component isn't matched as "active" when its descendant paths are matched. See NavLink for more component details.