React Bootstrap NavDropdown link overriding NavDropdown.Item link

Viewed 790

We have a on our React application, and we are attempting to nest several <NavDropdown.Item /> within a <NavDropdown />.

enter image description here

In the screenshot above, clicking Tools routes to /tools, and clicking the dropdown options should link to /tools/shot-charts, /tools/team-stats-graphs, etc. You can see this in the code below:

import { Nav, Navbar, NavDropdown } from 'react-bootstrap';

<Navbar.Collapse id='basic-navbar-nav'>
    <div className='navbar-nav-wrapper'>
        <Nav>
            <NavDropdown
                title='Tools'
                as={Link}
                to='/tools'
                className={`${isTools ? 'selected' : ''}`}
                onMouseEnter={() => setIsToolsHovered(true)}
                onMouseLeave={() => setIsToolsHovered(false)}
                onClick={() => history.push('/tools')}
                show={isToolsHovered}
            >
                <NavDropdown.Item as={Link} to={'/tools/shot-charts'}>Shot Charts</NavDropdown.Item>
                <NavDropdown.Item as={Link} to={'/tools/team-scatter'}>Team Stats Graphs</NavDropdown.Item>
                <NavDropdown.Item as={Link} to={'/tools/player-scatter'}>Player Stats Graphs</NavDropdown.Item>
                <NavDropdown.Item as={Link} to={'/tools/model-fitting'}>Linear Regressions</NavDropdown.Item>
            </NavDropdown>
        </Nav>
    </div>
</Navbar.Collapse>

Currently when Shot Charts is clicked, the page renders twice, first with the /tools/shot-charts url and then immediately after to the /tools url. This is problem. It appears that onClick={() => history.push('/tools')} on the <NavDropdown /> is triggering even though Shot Charts is clicked rather than Tools.

If we remove onClick={() => history.push('/tools')}, then the 4 dropdown buttons work, however clicking on Tools then does not change the page. It looks like as={Link} and to='/tools' on the <NavDropdown /> aren't doing anything to make Tools clickable.

Is there anyway for the and the <NavDropdown.Item /.'s to be separate links as is described & coded above?

1 Answers

I don't think there should be a link to prop and an onClick to effectively do the same thing on the outer NavDropdown, but the issue is likely that the onClick event from the nested NavDropdown.Item Links is propagating up to the NavDropdown.

I suggest removing the onClick handler on NavDropdown, and adding an onClick handler to the nested NavDropdown.Item components to stop the propagation of the click event.

const stopClickPropagation = event => event.stopPropagation();

...

<NavDropdown
  title='Tools'
  as={Link}
  to='/tools'
  className={`${isTools ? 'selected' : ''}`}
  onMouseEnter={() => setIsToolsHovered(true)}
  onMouseLeave={() => setIsToolsHovered(false)}
  show={isToolsHovered}
>
  <NavDropdown.Item
    as={Link}
    to={'/tools/shot-charts'}
    onClick={stopClickPropagation}
  >
    Shot Charts
  </NavDropdown.Item>
  <NavDropdown.Item
    as={Link}
    to={'/tools/team-scatter'}
    onClick={stopClickPropagation}
  >
    Team Stats Graphs
  </NavDropdown.Item>
  <NavDropdown.Item
    as={Link}
    to={'/tools/player-scatter'}
    onClick={stopClickPropagation}
  >
    Player Stats Graphs
  </NavDropdown.Item>
  <NavDropdown.Item
    as={Link}
    to={'/tools/model-fitting'}
    onClick={stopClickPropagation}
  >
    Linear Regressions
  </NavDropdown.Item>
</NavDropdown>
Related