使用 React Router 4 渲染嵌套组件时发生冲突
Conflict while rendering nested components with React Router 4
我在使用 React Router 4 进行路由时遇到问题。当使用 "nested" 路由时,其中一个顶级路由呈现了一个与该路由匹配的组件,但我不希望它被呈现。我将把重要的代码放在这里,并解释我想要实现的目标。这是我的 main/top 级路由,我删除了一些与问题无关的代码行:
这是我的 App.js
文件:
import React, {Component} from 'react';
import {Route} from 'react-router-dom';
import {withRouter} from 'react-router';
import {connect} from 'react-redux';
import {mapStateToProps, mapDispatchToProps} from './selector';
import HomeView from './packages/home-view';
import HardwareView from './packages/hardware-view';
import HardwareAddView from './packages/hardware-add-view';
import HardwareTypesAddView from './packages/hardware-types-add-view';
class App extends Component {
render() {
return (
<div className="App">
<main>
<Route exact path="/" component={HomeView} />
<Route path="/hardware" component={HardwareView} />
<Route exact path="/hardware/add" component={HardwareAddView} />
<Route exact path="/hardware/types/add" component={HardwareTypesAddView} />
</main>
</div>
);
}
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App));
HomeView
组件暂时只呈现一个空 <div/>
。
现在让我们进入 HardwareView
组件。在这个组件中,我正在渲染一个来自 material-ui 的 <Tabs/>
组件。这个 <Tabs/>
组件将有 2 个选项卡,每个选项卡都有自己的组件作为内容。所以为了说明,可以这样看:
App.js (div.App -> main)
+--------------------------------------------------------------------------+
| |
| hardware-view.js (Tabs component) |
| +---------------------------------------------------------------+ |
| | Hardware | Hardware Types | |
| | (Link to="/hardware") | (Link to="/hardware/types") | |
| +---------------------------------------------------------------+ |
| | Tab Content: | |
| | | |
| | A table that is served only when the exact path is "/hardware"| |
| | if the Hardware tab is selected. Or the content from | |
| | "/hardware/types" if the Hardware Types tab is selected | |
| | | |
| | - HardwareList for "/hardware" | |
| | - HardwareTypesList for "/hardware/types" | |
| +---------------------------------------------------------------+ |
+--------------------------------------------------------------------------+
选择任何选项卡时呈现的两个选项卡内容组件(HardwareList 或 HardwareTypesList)都将包含一个 link 按钮,该按钮将导航到 /hardware/add
或 /hardware/types/add
.这就是问题所在。当我导航到 /hardware/add
或 /hardware/types/add
时,我想呈现一个没有 <Tabs/>
组件的完整新视图,但这是不可能的,因为路由<Route path="/hardware" component={HardwareView} />
匹配 /hardware/add
或 /hardware/types/add
,因为它没有 exact
属性。
这是我的 packages/hardware-view/index.js
文件,其中包含 HardwareView
组件:
import React, {Component} from 'react';
import Paper from 'material-ui/Paper';
import {Tabs, Tab} from 'material-ui/Tabs';
import {Route, Link} from 'react-router-dom';
import HardwareList from '../hardware-list';
import HardwareTypesList from '../hardware-types-list';
export default class HardwareView extends Component {
render() {
const {location} = this.props;
const {pathname} = location;
return (
<div className="hardware-view-component">
<Paper zDepth={2}>
<Tabs value={pathname}>
<Tab label="Hardware" containerElement={<Link to="/hardware" />} value="/hardware">
<div className="tab-content">
<Route exact path="/hardware" component={HardwareList} />
</div>
</Tab>
<Tab label="Hardware Types" containerElement={<Link to="/hardware/types" />} value="/hardware/types">
<div className="tab-content">
<Route exact path="/hardware/types" component={HardwareTypesList} />
</div>
</Tab>
</Tabs>
</Paper>
</div>
);
}
}
我曾尝试使用 described here 的布局方法,但没有成功。我知道我可能想得太多了,对此有一种更干净的方法。关于如何实现我正在寻找的任何建议或 guide?
TLDR;
尝试在路由内渲染路由,但由于路由的路径,URL 的基本路径正在渲染顶级组件。例如 /foo
呈现 "Component A",/foo/bar
呈现 "Component A" 并在 A 内具有 "Component B",但我希望 /foo/bar/baz
仅呈现 "Component C" 并且它正在渲染 "Component A" 和 "Component C".
Switch
呈现匹配位置 (source: docs)
的第一个子 <Route>
或 <Redirect>
<Switch>
<Route exact path="/" component={HomeView} />
<Route exact path="/hardware/add" component={HardwareAddView} />
<Route exact path="/hardware/types/add" component={HardwareTypesAddView} />
<Route path="/hardware" component={HardwareView} />
</Switch>
我在使用 React Router 4 进行路由时遇到问题。当使用 "nested" 路由时,其中一个顶级路由呈现了一个与该路由匹配的组件,但我不希望它被呈现。我将把重要的代码放在这里,并解释我想要实现的目标。这是我的 main/top 级路由,我删除了一些与问题无关的代码行:
这是我的 App.js
文件:
import React, {Component} from 'react';
import {Route} from 'react-router-dom';
import {withRouter} from 'react-router';
import {connect} from 'react-redux';
import {mapStateToProps, mapDispatchToProps} from './selector';
import HomeView from './packages/home-view';
import HardwareView from './packages/hardware-view';
import HardwareAddView from './packages/hardware-add-view';
import HardwareTypesAddView from './packages/hardware-types-add-view';
class App extends Component {
render() {
return (
<div className="App">
<main>
<Route exact path="/" component={HomeView} />
<Route path="/hardware" component={HardwareView} />
<Route exact path="/hardware/add" component={HardwareAddView} />
<Route exact path="/hardware/types/add" component={HardwareTypesAddView} />
</main>
</div>
);
}
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App));
HomeView
组件暂时只呈现一个空 <div/>
。
现在让我们进入 HardwareView
组件。在这个组件中,我正在渲染一个来自 material-ui 的 <Tabs/>
组件。这个 <Tabs/>
组件将有 2 个选项卡,每个选项卡都有自己的组件作为内容。所以为了说明,可以这样看:
App.js (div.App -> main)
+--------------------------------------------------------------------------+
| |
| hardware-view.js (Tabs component) |
| +---------------------------------------------------------------+ |
| | Hardware | Hardware Types | |
| | (Link to="/hardware") | (Link to="/hardware/types") | |
| +---------------------------------------------------------------+ |
| | Tab Content: | |
| | | |
| | A table that is served only when the exact path is "/hardware"| |
| | if the Hardware tab is selected. Or the content from | |
| | "/hardware/types" if the Hardware Types tab is selected | |
| | | |
| | - HardwareList for "/hardware" | |
| | - HardwareTypesList for "/hardware/types" | |
| +---------------------------------------------------------------+ |
+--------------------------------------------------------------------------+
选择任何选项卡时呈现的两个选项卡内容组件(HardwareList 或 HardwareTypesList)都将包含一个 link 按钮,该按钮将导航到 /hardware/add
或 /hardware/types/add
.这就是问题所在。当我导航到 /hardware/add
或 /hardware/types/add
时,我想呈现一个没有 <Tabs/>
组件的完整新视图,但这是不可能的,因为路由<Route path="/hardware" component={HardwareView} />
匹配 /hardware/add
或 /hardware/types/add
,因为它没有 exact
属性。
这是我的 packages/hardware-view/index.js
文件,其中包含 HardwareView
组件:
import React, {Component} from 'react';
import Paper from 'material-ui/Paper';
import {Tabs, Tab} from 'material-ui/Tabs';
import {Route, Link} from 'react-router-dom';
import HardwareList from '../hardware-list';
import HardwareTypesList from '../hardware-types-list';
export default class HardwareView extends Component {
render() {
const {location} = this.props;
const {pathname} = location;
return (
<div className="hardware-view-component">
<Paper zDepth={2}>
<Tabs value={pathname}>
<Tab label="Hardware" containerElement={<Link to="/hardware" />} value="/hardware">
<div className="tab-content">
<Route exact path="/hardware" component={HardwareList} />
</div>
</Tab>
<Tab label="Hardware Types" containerElement={<Link to="/hardware/types" />} value="/hardware/types">
<div className="tab-content">
<Route exact path="/hardware/types" component={HardwareTypesList} />
</div>
</Tab>
</Tabs>
</Paper>
</div>
);
}
}
我曾尝试使用 described here 的布局方法,但没有成功。我知道我可能想得太多了,对此有一种更干净的方法。关于如何实现我正在寻找的任何建议或 guide?
TLDR;
尝试在路由内渲染路由,但由于路由的路径,URL 的基本路径正在渲染顶级组件。例如 /foo
呈现 "Component A",/foo/bar
呈现 "Component A" 并在 A 内具有 "Component B",但我希望 /foo/bar/baz
仅呈现 "Component C" 并且它正在渲染 "Component A" 和 "Component C".
Switch
呈现匹配位置 (source: docs)
<Route>
或 <Redirect>
<Switch>
<Route exact path="/" component={HomeView} />
<Route exact path="/hardware/add" component={HardwareAddView} />
<Route exact path="/hardware/types/add" component={HardwareTypesAddView} />
<Route path="/hardware" component={HardwareView} />
</Switch>