I\'m looking to build a tabs component, where some of the tabs will contain dynamic content. I originally started to follow this tutorial:
Creating a tabs component wit
I had a lot of issues setting this up (Nov 20, 2017) and thought I'd post the final setup here for posterity. I'm using react-router-dom 4.2.2
and material-ui 0.19.4
. Bascially, you want to change the hash (#) when the user clicks tabs, and use the hash to find which tab to display. It works pretty well, but unfortunately it adds a tiny bit of a delay, not sure why and will update if I figure it out.
import React, { Component } from 'react';
import { Tabs, Tab } from 'material-ui/Tabs';
export default class TabsComponent extends Component {
constructor(props) {
super(props);
this.onActive = this.onActive.bind(this);
this.getDefaultActiveTab = this.getDefaultActiveTab.bind(this);
this.tabIndices = {
'#firsttab': 0,
'#secondtab': 1
};
}
onActive(tab) {
const tabName = tab.props.label.toLowerCase();
this.props.history.replace(`#${tabName}`); // https://reacttraining.com/react-router/web/api/history
}
getDefaultActiveTab() {
const hash = this.props.location.hash;
return this.tabIndices[hash];
}
render() {
return (
// ...
// ...
);
}
}
And... material-ui ^1.0.0-beta.26
import React, { Component } from 'react';
import Tabs, { Tab } from 'material-ui/Tabs';
import Paper from 'material-ui/Paper';
import { withRouter } from 'react-router-dom';
import Resources from '../resources/index.jsx';
import styled from 'styled-components';
const StyledTabs = styled(Tabs) `
margin:5px;
`;
class LinkableTabs extends Component {
constructor(props) {
super(props);
this.getDefaultActiveTab = this.getDefaultActiveTab.bind(this);
this.switchTab = this.switchTab.bind(this);
this.state = {
activeTabIndex: this.getDefaultActiveTab()
}
}
getDefaultActiveTab() {
const hash = this.props.location.hash;
let initTabIndex = 0;
this.props.tabs.forEach((x, i) => {
const label = x.label;
if (`#${label.toLowerCase()}` === hash) initTabIndex = i;
});
return initTabIndex;
}
switchTab(event, activeTabIndex) {
this.setState({ activeTabIndex });
//make shareable - modify URL
const tabName = this.props.tabs[activeTabIndex].label.toLowerCase();
this.props.history.replace(`#${tabName}`);
}
render() {
const { match, location, history, staticContext, ...nonrouterProps } = this.props; //https://github.com/DefinitelyTyped/DefinitelyTyped/issues/13689#issuecomment-296246134
const isScrollable = this.props.tabs.length > 2;
return (
{
this.props.tabs.map(x => )
}
{
this.props.tabs[this.state.activeTabIndex].component
}
);
}
}
export default withRouter(LinkableTabs);