gpt4 book ai didi

reactjs - 保持 Material UI 选项卡和 React Router 同步

转载 作者:行者123 更新时间:2023-12-02 17:00:55 24 4
gpt4 key购买 nike

有没有一种简单的方法来保持 Material UI 选项卡和 React 路由器同步?

基本上,我想在用户单击选项卡 [1] 时更改 URL,并且当用户使用非选项卡链接或按钮导航到不同页面时,选项卡应自动更改,当然还有直接访问[2] 以及页面刷新。

此外,如果也能拥有 React 路由器的非精确功能,那就太好了,所以 /foo /foo 选项卡均应处于事件状态和/foo/bar/1 .

[1]其他SO答案建议直接使用history api,这是react-router的好习惯吗?

[2] 我不确定它叫什么,我的意思是当用户加载时 /foo直接而不是加载/然后导航到/foo通过选项卡或链接

<小时/>

编辑:

我创建了一个包装器组件来完成这项工作,但有一些问题:

class CustomTabs extends React.PureComponent {
constructor() {
super();

this.state = {
activeTab: 0
}
}

setActiveTab(id) {
this.setState({
activeTab: id
});
return null;
}

render() {
return (
<div>
{this.props.children.map((tab,index) => {
return (
<Route
key={index}
path={tab.props.path||"/"}
exact={tab.props.exact||false}
render={() => this.setActiveTab(index)}
/>
);
})}
<Tabs
style={{height: '64px'}}
contentContainerStyle={{height: '100%'}}
tabItemContainerStyle={{height: '100%'}}
value={this.state.activeTab}
>
{this.props.children.map((tab,index) => {
return (
<Tab
key={index}
value={index}
label={tab.props.label||""}
style={{paddingLeft: '10px', paddingRight: '10px', height: '64px'}}
onActive={() => {
this.props.history.push(tab.props.path||"/")
}}
/>
);
})}
</Tabs>
</div>
);
}
}

我这样使用它:

<AppBar title="Title" showMenuIconButton={false}>
<CustomTabs history={this.props.history}>
<Tab label="Home" path="/" exact/>
<Tab label="Foo" path="/foo"/>
<Tab label="Bar" path="/bar"/>
</CustomTabs>
</AppBar>

但是:

  • 我在控制台中收到此警告:

Warning: setState(...): Cannot update during an existing state transition (such as within render or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to componentWillMount.

我认为这是因为我在render()之后立即设置了状态被称为 - 因为 Route.render ,但我不知道如何解决这个问题。

<小时/>

编辑#2

我终于解决了所有问题,但方式有点古怪。

class CustomTabsImpl extends PureComponent {
constructor() {
super();

this.state = {
activeTab: 0
}
}

componentWillMount() {
this.state.activeTab = this.pathToTab(); // eslint-disable-line react/no-direct-mutation-state
}

componentWillUpdate() {
setTimeout(() => {
let newTab = this.pathToTab();
this.setState({
activeTab: newTab
});
}, 1);
}

pathToTab() {
let newTab = 0;

this.props.children.forEach((tab,index) => {
let match = matchPath(this.props.location.pathname, {
path: tab.props.path || "/",
exact: tab.props.exact || false
});
if(match) {
newTab = index;
}
});

return newTab;
}

changeHandler(id, event, tab) {
this.props.history.push(tab.props['data-path'] || "/");
this.setState({
activeTab: id
});
}

render() {
return (
<div>
<Tabs
style={{height: '64px'}}
contentContainerStyle={{height: '100%'}}
tabItemContainerStyle={{height: '100%'}}
onChange={(id,event,tab) => this.changeHandler(id,event,tab)}
value={this.state.activeTab}
>
{this.props.children.map((tab,index) => {
return (
<Tab
key={index}
value={index}
label={tab.props.label||""}
data-path={tab.props.path||"/"}
style={{height: '64px', width: '100px'}}
/>
);
})}
</Tabs>
</div>
);
}
}

const CustomTabs = withRouter(CustomTabsImpl);

最佳答案

首先感谢您对您的问题的回复。我以不同的方式处理这个问题,我决定在这里发帖以供社区赞赏。

我的理由是:“如果我可以告诉 Tab 而不是 Tabs 组件哪一个处于事件状态,那就更简单了。”

实现这一点非常简单,可以通过为 Tabs 组件设置一个已知的固定值并将该值分配给任何应该处于事件状态的选项卡来实现这一点。

此解决方案要求托管选项卡的组件能够访问 react 路由器的位置和匹配等属性,如下所示

<小时/>

首先,我们创建一个工厂函数,从渲染方法中删除臃肿的代码。如果所需的路线匹配,这里将固定 Tabs 值设置为 Tab,否则我只是抛出一个任意常量,例如 Infinity。

const mountTabValueFactory = (location, tabId) => (route) => !!matchPath(location.pathname, { path: route, exact: true }) ? tabId : Infinity;

<小时/>

之后,您只需将信息插入渲染函数即可。

render() {
const {location, match} = this.props;
const tabId = 'myTabId';
const getTabValue = mountTabValueFactory(location, tabId);

return (
<Tabs value={tabId}>
<Tab
value={getTabValue('/route/:id')}
label="tab1"
onClick={() => history.push(`${match.url}`)}/>
<Tab
value={getTabValue('/route/:id/sub-route')}
label="tab2"
onClick={() => history.push(`${match.url}/sub-route`)}
/>
</Tabs>
)
}

关于reactjs - 保持 Material UI 选项卡和 React Router 同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43947146/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com