reactjsdropdownmenuitemdropdownbuttonmenu-items

React: CSVLink not working when put inside MenuItem in DropdownButton


I have code in a React file like this:

    import {Dropdown, DropdownButton, MenuItem} from "react-bootstrap";
    import {CSVLink} from "react-csv";
    <DropdownButton id={'sdfsd'} title={
      <>
        <img src={exportIcon}/>Export
      </>
    }>
      <MenuItem>
        <CSVLink data={myCsvData} filename={`first-case.csv`}>First Case</CSVLink>
      </MenuItem>
      <MenuItem>
        <CSVLink data={mySecondCsvData} className="link" filename={`second-case.csv`}>Second Case</CSVLink>
      </MenuItem>
    </DropdownButton>
    

You can see that the CSVLink is wrapped inside MenuItem. It's used to download Excel sheet with the data, but it's not working now. When I click on it, nothing is happening.

How to make it work?


Solution

  • After a lot of struggle, I'm able to find the reason behind this.

    First of all, the component MenuItem is only available in react-bootstrap version v0.33.1 where as the latest version available as of now is v2.7.2. There are a huge number of changes between the two versions, so please use the latest if you can.

    The solution to this is add the prop "header" to the MenuItem like this:

    <MenuItem header>
        ....
    <MenuItem/>
    

    This prop styles the menu item as a header label, and is useful for describing a group of menu items or items with links present in them.

    Reason behind this:

    If you don't put the prop header, it compiles to html code:

    <a href="#">
        ......
    </a>
    

    You can see that it wraps inner elements with href="#", so, when you click on the element, this href gets triggered.

    If you look at the source code, it says,

    if (this.props.header) {
      children = this.props.children;
    } else if (!this.props.divider) {
      children = React.createElement("a", { onClick: this.handleClick, href: this.props.href, title: this.props.title, tabIndex: "-1" },
        this.props.children
      )
    }