在我的项目中,我必须在不更改 url 的情况下从一个组件导航到另一个组件。为此,我使用了 MemoryRouter
这按预期工作。但现在同样的想法应该适用于不同的路线,即 /one
和 /two
.例如,
/one --> BrowserRouter (url change visible)
/
/first
/second
/third
/two --> BrowserRouter (url change visible)
/
/first
/second
/third
对于新的可见路由,即
/one
和 /two
,已经建立的工作内存路由(即 /
、 /first
、 /second
、 /third
)应该按照 /one
中提供的相应数据正常工作和 /two
.我正在努力使用以下结构代码将 MemoryRoutes 包含在 BrowserRoutes 中:
<BrowserRouter>
<Switch>
<Route path="/one" render={() => <MemoryComp configFor="Dave"></MemoryComp>}></Route>
<Route path="/two" render={() => <MemoryComp configFor="Mike"></MemoryComp>}></Route>
</Switch>
</BrowserRouter>
然后是
MemoryComp
持有: <MemoryRouter history={customHistory}>
<Switch>
<Route path="/" render={(props) => <InitPage configFor={this.props.configFor} history={props.history}></InitPage>}></Route>
<Route path="/first" component={FirstPage}></Route>
<Route path="/second" component={SecondPage}></Route>
<Route path="/third" component={ThirdPage}></Route>
</Switch>
</MemoryRouter>
我正在努力实现的目标:
history
来实现相同的效果)笔记:
这更有可能更好地用服务器路由来处理浏览器路由内容。此外,这似乎可以通过任何 react-stepper 插件来实现。但试图了解我在这里做错了什么,只是为了学习目的。
这是完整的最小化代码,可在 Stackblitz 上找到(不工作):
import React, { Component } from 'react';
import { render } from 'react-dom';
import './style.css';
import { BrowserRouter, MemoryRouter, Route, Switch } from 'react-router-dom';
import { createBrowserHistory } from "history";
const customHistory = createBrowserHistory();
class MemoryComp extends Component{
render(){
return(
<MemoryRouter history={customHistory}>
<Switch>
<Route path="/" render={(props) => <InitPage configFor={this.props.configFor} history={props.history}></InitPage>}></Route>
<Route path="/first" component={FirstPage}></Route>
<Route path="/second" component={SecondPage}></Route>
<Route path="/third" component={ThirdPage}></Route>
</Switch>
</MemoryRouter>
);
}
}
class InitPage extends Component{
render(){
return (
<>
<ul>
<li onClick={() => this.navigateTo("/")}>Init</li>
<li onClick={() => this.navigateTo("/first")}>First</li>
<li onClick={() => this.navigateTo("/second")}>Second</li>
<li onClick={() => this.navigateTo("/third")}>Third</li>
</ul>
<div>{this.props.configFor}</div>
</>
)
}
navigateTo(path){
this.props.history.push(path, {
data: {
configFor: this.props.configFor
}
})
}
}
class FirstPage extends Component{
constructor(props){
super(props);
this.data = this.props.history.location.state.data;
}
render(){
return (
<>
<ul>
<li onClick={() => this.navigateTo("/")}>Init</li>
<li onClick={() => this.navigateTo("/first")}>First</li>
<li onClick={() => this.navigateTo("/second")}>Second</li>
<li onClick={() => this.navigateTo("/third")}>Third</li>
</ul>
<div>first page</div>
</>
)
}
navigateTo(path){
this.props.history.push(path, {
data: {...this.data, ...{pageName: 'first'}}
})
}
}
class SecondPage extends Component{
constructor(props){
super(props);
this.data = this.props.history.location.state.data;
}
render(){
return (
<>
<ul>
<li onClick={() => this.navigateTo("/")}>Init</li>
<li onClick={() => this.navigateTo("/first")}>First</li>
<li onClick={() => this.navigateTo("/second")}>Second</li>
<li onClick={() => this.navigateTo("/third")}>Third</li>
</ul>
<div>second page</div>
</>
)
}
navigateTo(path){
this.props.history.push(path, {
data: {...this.data, ...{name: 'deducedValue'}}
})
}
}
class ThirdPage extends Component{
constructor(props){
super(props);
this.data = this.props.history.location.state.data;
}
render(){
return (
<>
<ul>
<li onClick={() => this.navigateTo("/")}>Init</li>
<li onClick={() => this.navigateTo("/first")}>First</li>
<li onClick={() => this.navigateTo("/second")}>Second</li>
<li onClick={() => this.navigateTo("/third")}>Third</li>
</ul>
<div>third page</div>
</>
)
}
navigateTo(path){
this.props.history.push(path, {
data: this.data
})
}
}
class App extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
render() {
return (
<div>
<BrowserRouter>
<Switch>
<Route path="/one" render={() => <MemoryComp configFor="Dave"></MemoryComp>}></Route>
<Route path="/two" render={() => <MemoryComp configFor="Mike"></MemoryComp>}></Route>
</Switch>
</BrowserRouter>
</div>
);
}
}
render(<App />, document.getElementById('root'));
最佳答案
一开始我以为Switch
有问题结合 MemoryRouter
,但经过一些调试后,我意识到它实际上是完全独立的。
您遇到的问题是您的基本内存路由需要是 exact
,否则所有其他路由将匹配该路由,并且将返回第一个 ('/')。只需添加 exact
到您的基本路线。
<MemoryRouter>
<Switch>
<Route exact path="/" render={(props) => <InitPage configFor={this.props.configFor} history={props.history}></InitPage>}></Route>
<Route path="/first" component={FirstPage}></Route>
<Route path="/second" component={SecondPage}></Route>
<Route path="/third" component={ThirdPage}></Route>
</Switch>
</MemoryRouter>
如果您有更多的嵌套路由总是添加精确到根,请小心,例如
/first
需要准确才能使其正常工作:<Route exact path="/first" component={FirstPage}></Route>
<Route path="/first/nested-1" component={SecondPage}></Route>
<Route path="/first/nested-2" component={ThirdPage}></Route>
关于reactjs - 在 BrowserRouter 中使用 MemoryRouter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60716732/