我正在使用Material UI和React,我正在以编程方式创建多个选项卡,如下所示:
return (
<div>
<Tabs>
{this.state.elements.map(elem => {
return (
<Tab key={elem.elemID} label={elem.name} >
<div>
// rest removed for brevity
</div>
</Tab>
)
})}
</Tabs>
</div>
);
这是有效的,并且显示选项卡,但问题是默认情况下,当组件呈现时,第一个选项卡是活动选项卡。然而,我想根据我从道具获得的id值以编程方式设置活动选项卡。所以基本上,如果this.props.selectedID === elem.elemID
然后我希望该选项卡是组件呈现时的活动选项卡。当然,一旦呈现组件,用户应该可以自由地单击并在选项卡之间切换。知道如何实现它吗?
在value
和Tabs
上使用Tab
prop使其成为受控组件:
<Tabs value={this.props.selectedID}>
{this.state.elements.map(elem => {
return (
<Tab key={elem.elemID} label={elem.name} value={elem.elemID}>
<div>
// rest removed for brevity
</div>
</Tab>
)
})}
</Tabs>
TL DR;假设您正在尝试将其映射到URL,这里的技巧是以编程方式将<Tab>
的“value”属性设置为URL当前具有的属性。我假设你正在使用React Router。
例:
const baseUrls = ['', 'online-manga-reader', 'admin'];
class TabBar extends React.Component {
constructor(props) {
super(props);
this.state = {
value: this.processPathName(),
};
}
processPathName(){
const path = this.props.location.pathname.split('/')[1];
const value = baseUrls.indexOf(path);
return value !== -1 ? value : 0; // This is the default one.
}
handleChange = (event, value) => {
this.setState({ value });
this.returnTabContainer(value);
}
returnTabContainer(value) {
switch (value) {
case 1:
this.props.history.push('/online-manga-reader');
break;
case 2:
this.props.history.push('/admin/article');
break;
default:
this.props.history.push('/');
}
}
returnTabAdmin() {
return this.props.isAdmin ? <Tab label="Admin Tab" /> : '';
}
render() {
const { classes } = this.props;
const { value } = this.state;
return (
<div className={classes.root}>
<AppBar position="static">
<Tabs
value={value}
onChange={(evt, val) => {this.handleChange(evt, val); }}
>
<Tab label="Home" />
<Tab label="Online Manga Reader" />
{this.returnTabAdmin()}
</Tabs>
<LoginButton />
</AppBar>
</div>
);
}
}
export default connect(mapStateToProps)(withStyles(styles)(withRouter(TabBar)));
说明
const baseUrls = ['', 'online-manga-reader', 'admin'];
这是一个位于类外部的数组,它包含URL的第一个路径(或基本URL):
这将匹配基本URL(因此将选择第一个)http://example.com/
这一个,第二个将匹配
第三个: - http://example.com/admin - http://example.com/admin/article/create
我在这里使用的“技巧”在于processPathName()
方法。它从React-Router读取当前的URL,然后调用split,它已经在所需的部分中解析了你的URL:
http://example.com/admin/article/create
将翻译为:
/
admin
article
create
总是让我们回到1这个我们正在寻找的位置(这是分裂中的一个)。
有了它,我们使用好的'indexOf来搜索数组内部的路径。如果找到它,它将返回与我们的选项卡位置匹配的数字。这就是为什么它们按照相同的顺序排列是很重要的。
如果它没有找到它,我们设置一个默认值(在这种情况下,我们将其设置为零,这将占主页)。
您的商品应该正常呈现,没有任何问题。
这是我的答案,作为钩子的最小通用示例。我还假设你使用的是React Router。它实际上将url状态链接到Tab的'selectedness'(在更改和渲染时):
const NavTabs = ({ history, location }) => {
function getInitialTab() {
switch (true) {
case /\/componentone/.test(location.pathname):
return 0
case /\/componenttwo/.test(location.pathname):
return 1
default:
return 0
}
}
const [value, setValue] = useState(getInitialTab())
function handleChange(event, val) {
setValue(val)
switch (val) {
case 0:
history.push('/componentone')
break
case 1:
history.push('/componenttwo')
break
default:
break
}
}
return (
<NoSsr>
<div>
<AppBar position="static">
<Tabs
variant="fullWidth"
value={value}
onChange={handleChange}
>
<Tab label="Component One" />
<Tab label="Component Two" />
</Tabs>
</AppBar>
{value === 0 && (
<Typography component="div">
<ComponentOne history={history} location={location} />
</Typography>
)}
{value === 1 && (
<Typography component="div">
<ComponentTwo history={history} location={location} />
</Typography>
)}
</div>
</NoSsr>
)
}