2

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.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
usagibear
  • 303
  • 3
  • 12

1 Answers1

2

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.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Thanks Drew! I see, it was primarily because I was focused on react-bootstrap rather than react-router-dom, which actually has the history aware NavLink. The tricky part for me was understanding the `to` and `end` properties which actually allow linking (in place of `href`) and for resolving descendants parsing, respectively. https://reactrouter.com/en/main/components/link https://reactrouter.com/en/main/components/nav-link – usagibear Nov 10 '22 at 17:49
  • 1
    @usagibear Ah yes, sorry I didn't call that bit out why the home `"/"` path needs it (*it wasn't directly related to the issue you were asking for help with*). Sounds like you got that part sorted out though? – Drew Reese Nov 10 '22 at 17:52
  • Yes, it all makes sense now. I wanted to add the comment and resources for future folks if they are like me and may not know. Thanks again! – usagibear Nov 10 '22 at 18:03
  • @usagibear I updated my answer to include a brief note regarding the `end` prop. – Drew Reese Nov 10 '22 at 18:07