我正在寻找构建标签组件,其中一些标签将包含动态内容。我最初开始学习本教程:
Creating a tabs component with React
在阅读了react-router之后,似乎它也可以解决这个问题。什么是更好的方法和/或它有所作为?
答案 0 :(得分:7)
是的,这是React Router 的完美作业,因为它专注于简化单页应用的URL重定向过程。
用于导航的选项卡的用例,绝对属于React Router的范围。您可以使用React Router 3或4,但React Router 4 API is on the horizon和文档看起来很棒。
您可以在上面的链接中找到有用的示例,其中显示了与标签链接的简便性。和here is an example讨论了如何使用自定义链接创建标签。
其中一个" 陷阱 "虽然您可能想要考虑,但是如果您导航到不同的路线然后导航回到上一个路线,则恢复滚动位置会有一些困难。这是一个进一步讨论这个问题的主题:https://github.com/ReactTraining/react-router/issues/1686。
如果恢复滚动位置对您来说非常重要,那么此时React Router可能不适合标签。
更新
React router v4已经发布,上面的问题已经解决,现在文档上有how to restore scroll position的指南!
答案 1 :(得分:4)
我设置了很多问题(2017年11月20日)并且认为我在这里发布最终设置以供后代使用。我正在使用react-router-dom 4.2.2
和material-ui 0.19.4
。基本上,您希望在用户单击选项卡时更改哈希(#),并使用哈希查找要显示的选项卡。它工作得很好,但不幸的是它增加了一点延迟,不知道为什么,如果我搞清楚会更新。
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>
);
}
}
而且...... 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);