28

I have a web app that I'v designed with material-UI and as you can see below I'm using Button navigation for navigating through my basic landing page components.

<div className="footer">
  <BottomNavigation value={value} onChange={this.handleChange} className={classes.root}>
    <BottomNavigationAction label="signal" value="signal" icon={<ShowChart />} className={classes.content}/>
    <BottomNavigationAction label="hotlist" value="hotlist" icon={<HotList />} className={classes.content}/>
    <BottomNavigationAction label="analyze" value="analyze" icon={<PieChart />} className={classes.content}/>
    <BottomNavigationAction label="learn" value="learn" icon={<LibraryBooks/>} className={classes.content}/>
    <BottomNavigationAction label="dashboard" value="dashboard" icon={<PermIdentity/>} className={classes.content}/>
  </BottomNavigation>
  </div>

I've tried to use React-Router with these predefiend navigation component but that didn't work, is there any possible way to use Router with Button navigation of material-UI? Button navigation article in material-UI ButtonNavigation API

El.
  • 939
  • 1
  • 11
  • 18

2 Answers2

60

Yes, it's possible. You need to use the component prop:

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

import BottomNavigation from '@material-ui/core/BottomNavigation';
import BottomNavigationAction from '@material-ui/core/BottomNavigationAction';

// ....

<BottomNavigation value={value} onChange={this.handleChange}>
    <BottomNavigationAction
        component={Link}
        to="/signal"
        label="signal"
        value="signal"
        icon={<ShowChart />}
        className={classes.content}
    />
</BottomNavigation>

(the to prop is for React Router's Link component)

This works with any Material-UI component that inherits from ButtonBase.

https://material-ui.com/api/bottom-navigation-action/

Inheritance

The properties of the ButtonBase component are also available. You can take advantage of this behavior to target nested components.

https://material-ui.com/api/button-base/

Props

component - The component used for the root node. Either a string to use a DOM element or a component.

thirtydot
  • 210,355
  • 44
  • 377
  • 337
5

Just to add on to the great answer by @thirtydot , in case the user types into the search and visits a particular webpage directly (other than default) e.g. "www.yoursite.com/tab2", instead of clicking the 2nd button, this may cause a mismatch between the site that is showing and the BottomNav Button that is focused (usually the 1st button).

Here is what I did:
I used window.location.pathname to get the current path which is '/tab2' directly.
Here is my code for my particular use case....

function BottomNavBar(){
    const pathname = window.location.pathname; // in case user visits the path directly. The BottomNavBar is able to follow suit.
    const [value, setValue] = React.useState(pathname);
    const handleChange = (event, newValue) => {
      setValue(newValue);
    };

    return (
        <BottomNavigation value={value} onChange={handleChange} showLabels={true} >
          <BottomNavigationAction label="home" value="/" icon={<HomeIcon />} component={Link} to='/'/>
          <BottomNavigationAction label="resources" value="/resources" icon={<ResourcesIcon /> } component={Link} to='/resources'/>                
          <BottomNavigationAction label="Q&A" value="/qna" icon={<QnAIcon />}  component={Link} to='/qna'/>
          <BottomNavigationAction label="profile" value="/profile" icon={<ProfileIcon />} component={Link} to='/profile'/>
        </BottomNavigation>
      );
}

Daryll
  • 173
  • 2
  • 9
  • 1
    Read the answer by @thirtydot first. – Daryll May 23 '20 at 12:42
  • 1
    This is a smart workaround. Thanks! – mrKindo Jan 23 '21 at 12:59
  • @mcKindo No problem! Happy this helped – Daryll Apr 24 '21 at 17:10
  • An add on. Instead of using window.location.pathname (as you have to parse it.. think of the case if the url is '/tab2/123' instead), I believe for CRA users, most likely you will be using react-router-dom. You should use that instead to get the path. `import { useLocation } from 'react-router-dom'` or refer to this [other stackoverflow thread](https://stackoverflow.com/questions/42253277/react-router-v4-how-to-get-current-route) for other alternatives – Daryll Apr 24 '21 at 17:13