38

I am toying with material-ui. I implemented LeftNav using routes, but I could not find a way to get IconMenu, or Menu working with links or routes. Anyone can point me to a good source / tutorial? The documentation falls short, and both components seem not to support 'menuItems' as property as LeftNav does.

gattermeier
  • 471
  • 1
  • 5
  • 11

18 Answers18

71

another long overdue update:

containerElement prop is not supported anymore, use component prop instead.

Check out the document here.


2016 December Edit: the linkButton prop is deprecated, you will get a warning:

Warning: Unknown props `linkButton` on <a> tag.

So simply remove the prop:

<MenuItem
  containerElement={<Link to="/profile" />}
  primaryText="Profile"
  leftIcon={
    <FontIcon className="material-icons">people</FontIcon>
  }
/>

Here's an Example Repo, and the Live Demo Here.


Original answer:

Just wanted to point out that if you're using react-router, you might want to use <Link to="/some/page" /> rather than the <a> tag.

To do this, you need to use the containerElement prop

<MenuItem
  linkButton
  containerElement={<Link to="/profile" />}
  primaryText="Profile"
  leftIcon={
    <FontIcon className="material-icons">people</FontIcon>
  }
/>

(the ={true} can be omitted if you're only passing true, in other words, <MenuItem linkButton /> is same as <MenuItem linkButton={true} />)

The containerElement and linkButton props is actually documented in the buttons section, but you can use it in MenuItem as well.

DaxChen
  • 1,869
  • 1
  • 16
  • 21
41

Starting with Material-UI 1.0, the new syntax is:

<MenuItem
  component={Link}
  // the 'to' prop (and any other props not recognized by MenuItem itself)
  // will be passed down to the Link component
  to="/profile"
>
  Profile
</MenuItem>

(Note: this example doesn't include an icon. There is a new ListItemIcon component for that.)

Matt Browne
  • 12,169
  • 4
  • 59
  • 75
  • Perfect... As I needed. – prem30488 Oct 24 '19 at 06:25
  • This works with `ListItem` from Material UI as well. – piotros Mar 02 '21 at 08:59
  • 1
    Works in v5, which the top answer didn't for me – dading84 Mar 08 '22 at 16:03
  • Not a fan of passing down props implicitly, plus it wont work with typescript. Way better to just do this: `component={()=>}` – ICW Apr 18 '22 at 18:33
  • Maybe I'm doing smth wrong, but ``` const menuItems: MenuItemProps[] = [{id: 'someId', children: 'Go', component={Link}}] ``` and se the error - `Type '{ id: string; onClick: () => void; children: string; component: string; }' is not assignable to type 'MenuItemProps<"li", {}>'. Object literal may only specify known properties, and 'component' does not exist in type 'MenuItemProps<"li", {}>'. `. What's wrong with it? – lazy.lizard Apr 14 '23 at 13:44
13

You can set the linkButtton prop on MenuItem to generate a link, then also add an href.

<MenuItem linkButton={true} href="link/to/some/page" primaryText="Sample Link" />
Hai Nguyen
  • 4,059
  • 1
  • 20
  • 16
11

None of the existing answers (of September 2018) worked for me with react 16.4.2 and react-router 4.2.2, so this was my solution:

<Link to='/notifications' style={{ textDecoration: 'none' }}>
   <MenuItem>Notifications</MenuItem>
</Link>

As you can see, the MenuItem component is surrounded by the Link component, and I added a style textDecoration: 'none' not to have the item underlined.

Simon
  • 6,025
  • 7
  • 46
  • 98
8

As of Sep 2020, only thing that works and is super simple is

<MenuItem component="a" href="/your-path">Click Me</MenuItem>

Bonus: To add icon with a badge:

<MenuItem component="a" href="/your-path">
        <IconButton color="inherit" href="/your-path">
              <Badge badgeContent="12" color="secondary">
                <StarsSharpIcon color="action"/>
              </Badge>
        </IconButton>
Click Me
</MenuItem>
Kal
  • 1,656
  • 4
  • 26
  • 41
7

The prop linkButton of EnhancedButton is deprecated. LinkButton is no longer required when the href property is provided. It will be removed with v0.16.0.

<MenuItem onTouchTap={this.handleClose} href="/link/data">Link Item</MenuItem>

Works fine

Shashwat
  • 525
  • 4
  • 8
  • this is the best answer as of 11/29/2016 you can also use things like `target="_blank"` to get the link to open in a new browser window – Chris Sprance Nov 29 '16 at 06:42
  • This is an option but that will reload the whole page, while `Link`'s element doesn't. It's possible instead to simply wrap the `MenuItem`: ```Home``` – keepthepeach Nov 29 '16 at 07:18
5

Using M-UI 4.x you can set a component prop on MenuItem and to something like

<MenuItem component='a' href='link/to/some/page'>Sample Link</MenuItem>
Maxime Brehin
  • 377
  • 6
  • 4
3

After doing a little searching myself I went with a slightly different solution:

<MenuItem onClick={() => {handleClose("/#about")}}>About me</MenuItem>

With a supporting JS function:

function handleClose(nav) {
    window.location.href = nav;
}

Hopefully proves of use as an alternative.

Matthew
  • 385
  • 1
  • 2
  • 13
3
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import { Link } from 'react-router-dom';


<MenuItem component={Link} to='/login'>
       Login
</MenuItem>

That worked for me, September 2021, by using React Router and the Link prop of the MenuItem.

Dorian Naaji
  • 116
  • 1
  • 6
2

From v5.2.2 you can use:

import { MenuItem } from '@mui/material';
import { Link } from 'react-router-dom';

<MenuItem component={Link} to="/profile">
  Profile
</MenuItem>
Petr K.
  • 530
  • 6
  • 12
2

This worked for me with the v5

for external links

<MenuItem
    component={"a"}
    href={"https://example.com"}
>Go here</MenuItem>

or internal links

import { MenuItem } from "@mui/material";
import { Link } from "react-router-dom";
<MenuItem
    component={Link}
    to={"/users/2323"}
>Go here</MenuItem>
KhaledMohamedP
  • 5,000
  • 3
  • 28
  • 26
2

We should use <Link> tag out side of <MenuItem> tag

Error:

     <MenuItem>
        <ListItemText>
            <Link to='/ticket-blotter' style={{ textDecoration: 'none' }}>
                TICKET BLOTTER 
            </Link>
        </ListItemText>
     </MenuItem>
       

Solution:

        <Link to='/ticket-blotter' style={{ textDecoration: 'none' }}>
            <MenuItem>
                <ListItemText>
                    TICKET BLOTTER
                </ListItemText>
            </MenuItem>
        </Link>
KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
2

2023 Answer:

import {Menu, MenuItem, Link} from '@mui/material'

<Menu>
  <MenuItem component={Link} href='/'>Home</MenuItem>
  <MenuItem component={Link} href='/settings/user'>My Settings</MenuItem>
<Menu />

As of writing in 2023 a lot of the answers above have been deprecated, tested using MUI v5.11.6.

Passing in a Link as the component prop of a MenuItem, uses a Link as the root element of that MenuItem. Documentation on additional things you can do with a Link element can be found here

Matt Davis
  • 1,167
  • 8
  • 21
  • Cheers! This one works best despite some other solutions also working. It doesn't add any additional styling. – Tajs Feb 15 '23 at 11:32
1

onTouchTap doesn't work for me I have to use onClick see the example below

  <MenuItem 
    onClick={this.logout}
    containerElement={<Link to="/" />}
    primaryText="Sign out"
    rightIcon={
      <b style={style.rightIcon}>
        <img
          className="menu-img"
          src="img/app/logout.png"
          alt="logout"
        />
      </b>
    }
  />

hope this will help others as well

JGallardo
  • 11,074
  • 10
  • 82
  • 96
Manish
  • 639
  • 6
  • 17
1

You can use react-route-dom and MenuItem onClick attribute first import react-router-dom: import { useHistory } from 'react-router-dom' then declare a function to handle your onClick within your component: const navigate = () => history.push('route/to/navigate') and then user your MenuItem <MenuItem onClick={navigate}>Navigate</MenuItem>

0

Here is my implementation, which looks exactly like what in the material-ui official website. The component you can use include AppBar, Drawer and ListItem. The SelectableList can be implemented as let SelectableList = MakeSelectable(List).

<div>
  <AppBar 
    onLeftIconButtonTouchTap={this.handleLeftIconButtonTouchTap}
    title={title}
    showMenuIconButton={true}
    zDepth={0}
  />
    <Drawer 
      open={this.state.open} 
      docked={true} 
      onRequestChange={(open, reason) => {
        this.setState({open:false})
      }}
    >
      <AppBar title={title} />
      <SelectableList
        value={location.pathname}
        onChange={this.handleRequestChangeList}
       >
        <Subheader>Selectable Contacts</Subheader>
        <ListItem
          value={"link1"}
          primaryText="Link1"
        />
        <ListItem
          value={"link2"}
          primaryText="Link2"
        />
      </SelectableList>
    </Drawer>
 </div>
JGallardo
  • 11,074
  • 10
  • 82
  • 96
Shawn Zhang
  • 153
  • 1
  • 5
0

I couldn't make the containerElement work on Safari in iOS with react-router. I'm using 0.17.2 of Material UI and react-router@v3 and here's a work around that worked for me:

  <MenuItem
    onTouchTap={() => {
      this._yourMethod()
      browserHistory.push('/howItWorks')
    }}
    primaryText="Menu Link"
  />
JohnnyQ
  • 4,839
  • 6
  • 47
  • 65
0

This way worked for me

import { useHistory } from 'react-router-dom';

const YourComponentName = () =>{
  
    const history = useHistory();
    const handleRoutes = (path) =>{
       history.push(path)
    }
    
  return(
    <>
      ...
      <MenuItem onClick={()=>handleRoutes('/dashboard')}>Dashboard</MenuItem>
      <MenuItem onClick={()=>handleRoutes('/profile')}>Profile</MenuItem>
      ...
    </>
)
}