Material-UI's Tabs integration with react router 4? Material-UI's Tabs integration with react router 4? reactjs reactjs

Material-UI's Tabs integration with react router 4?


Another solution (https://codesandbox.io/s/l4yo482pll) with no handlers nor HOCs, just pure react-router and material-ui components:

import React, { Fragment } from "react";import ReactDOM from "react-dom";import Tabs from "@material-ui/core/Tabs";import Tab from "@material-ui/core/Tab";import { Switch, Route, Link, BrowserRouter, Redirect } from "react-router-dom";function App() {  const allTabs = ['/', '/tab2', '/tab3'];  return (    <BrowserRouter>      <div className="App">        <Route          path="/"          render={({ location }) => (            <Fragment>              <Tabs value={location.pathname}>                <Tab label="Item One" value="/" component={Link} to={allTabs[0]} />                <Tab label="Item Two" value="/tab2" component={Link} to={allTabs[1]} />                <Tab                  value="/tab3"                  label="Item Three"                  component={Link}                  to={allTabs[2]}                />              </Tabs>              <Switch>                <Route path={allTabs[1]} render={() => <div>Tab 2</div>} />                <Route path={allTabs[2]} render={() => <div>Tab 3</div>} />                <Route path={allTabs[0]} render={() => <div>Tab 1</div>} />              </Switch>            </Fragment>          )}        />      </div>    </BrowserRouter>  );}const rootElement = document.getElementById("root");ReactDOM.render(<App />, rootElement);


My instructor helped me with using React Router 4.0's withRouter to wrap the Tabs component to enable history methods like so:

import React, {Component} from "react";import {Tabs, Tab} from 'material-ui';import { withRouter } from "react-router-dom";import Home from "./Home";import Portfolio from "./Portfolio";class NavTabs extends Component { handleCallToRouter = (value) => {   this.props.history.push(value); }  render () {     return (      <Tabs        value={this.props.history.location.pathname}        onChange={this.handleCallToRouter}        >        <Tab          label="Home"          value="/"        >        <div>           <Home />        </div>        </Tab>        <Tab          label="Portfolio"          value="/portfolio"            >          <div>            <Portfolio />          </div>        </Tab>      </Tabs>               )  }}export default withRouter(NavTabs)  

Simply add BrowserRouter to index.js and you're good to go.


The error you are seeing from material-ui is because it expects to have a <Tab> component rendered as direct child of <Tabs> component.

Now, here is a way that I've found to integrate the link into the <Tabs> component without loosing the styles:

import React, {Component} from 'react';import {Tabs, Tab} from 'material-ui/Tabs';import {Link} from 'react-router-dom';export default class MyComponent extends Component {    render() {        const {location} = this.props;        const {pathname} = location;        return (            <Tabs value={pathname}>                <Tab label="First tab" containerElement={<Link to="/my-firs-tab-view" />} value="/my-firs-tab-view">                    {/* insert your component to be rendered inside the tab here */}                </Tab>                <Tab label="Second tab" containerElement={<Link to="/my-second-tab-view" />} value="/my-second-tab-view">                    {/* insert your component to be rendered inside the tab here */}                </Tab>            </Tabs>        );    }}

To manage the 'active' property for the tabs, you can use the value property in the <Tabs> component and you also need to have a value property for each tab, so when both of the properties match, it will apply the active style to that tab.