Should I use an interactive router for the tab component?

I want to create a tabs component where some tabs will contain dynamic content. First, I started following this guide:

Creating a Tab Component with React

After reading the reaction on the router, it seems that it can also solve this problem. What would be the best approach and / or may it matter?

+5
javascript reactjs react-router tabs
source share
2 answers

Yes, this is an ideal job for React Router because it focuses on simplifying the URL redirection process for Single Pages Apps.

The option of using tabs for navigation definitely falls under React Router. You can use React Router 3 or 4 for this, but the React Router 4 API is on the horizon and the documentation looks great.

In the link above, you can find a useful example that shows how easily it links to tabs. And here is an example that discusses how to create tabs with custom links.

One of the " gotchas ", although you might want to consider, is that there were some difficulties in restoring the scroll position if you go to another route and then go to the previous route. Below is the thread that discusses this issue further : https://github.com/ReactTraining/react-router/issues/1686 .

If it’s very important for you to restore the scroll position , then at this point the React Router may not be the best choice for tabs.

+6
source share

I had a lot of problems with this (November 20, 2017) and I thought that I would send the final setup here for posterity. I am using react-router-dom 4.2.2 and material-ui 0.19.4 . Basically, you want to change the hash (#) when the user clicks the tabs, and use the hash to find which tab to display. It works very well, but unfortunately it adds a tiny delay, not sure why and will be updated if I find 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 ( <Tabs initialSelectedIndex={this.getDefaultActiveTab()} > <Tab label="FirstTab" onActive={this.onActive} > // ... </Tab> <Tab label="SecondTab" onActive={this.onActive} > // ... </Tab> </Tabs> ); } } 

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 ( <div> <Paper> <StyledTabs fullWidth centered scrollable={isScrollable} onChange={this.switchTab} value={this.state.activeTabIndex} {...nonrouterProps} > { this.props.tabs.map(x => <Tab key={x.label} label={x.label} />) } </StyledTabs> </Paper> { this.props.tabs[this.state.activeTabIndex].component } </div> ); } } export default withRouter(LinkableTabs); 
+2
source share

All Articles