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.