1、需求
最近在看一点React,稍微学习一点知识。在学习过程中照着书扒代码时发现书上的react-router部分的代码完全不能用。主要原因为书上的react-router版本是3.x,而且当前建立网页应用时一般使用的是react-router-dom库,版本已经是5.x,API有了巨大的变化。
比如原来的路由嵌套,现在完全没用了,IndexRoute、browserHistory等等也没有了。而且原来<Route />组件中的path="home"前面可以不加“/”,但现在如果不写成“/home”,路由无法跳转到localhost/home页面。
现在练习时需要建立这样一个多页应用(伪):有一个登录页、一个404页、然后是业务页组,其中业务页均有个共同的导航页头或其他导航组件。
2、尝试失败记录
首先构建了登录页组件Login、404页组件NotFound、业务页组件 Home、User,以及导航组件Topbar。
书上的嵌套路由虽然似乎没用,但是似乎可以通过组件嵌套实现业务组件页有共同的Topbar:
//构建如下的Topbar,使其子组件正确渲染 import React from 'react'; import {Link} from 'react-router-dom'; const Topbar=({children})=>{ return ( <div> <ul> <li><Link to="/home">Home</Link></li> <li><Link to="/about">About</Link></li> </ul> {children} </div> ); } export default Topbar ;
//App如下
import {BrowserRouter as Router,Redirect,Route,Switch} from 'react-router-dom';
function App() {
return (
<div className="App">
<Router>
<Switch>
<Route exact path="/login" component={Login} />
<Route exact path="/404" component={NotFound} />
<Topbar>
<Route exact path="/" component={Home}/>
<Route exact path="/user" component={User} />
</Topbar>
<Redirect to="/login"/>
</Switch>
</Router>
</div>
);
结果是:路由可以生效,但不在路由表里的URL,无法由Redirect组件跳转到“/”路径,没有搞明白是什么情况。。所以还是不能用(试过把Topbar组件用withRouter包裹,但是也是同样问题)。
3、另一种方法(多级React路由)
这里在网上又看到另一种方法,把不需要共同导航的页面放在上面,业务页面构建二级路由:
function App() {
return (
<div className="App">
<Router>
<Switch>
<Route exact path="/login" component={Login} />
<Route exact path="/404" component={NotFound} />
<Route path="/" component={Root}/> //二级路由入口,由一个新的Root组件进入,注意不能使用exact
</Switch>
</Router>
</div>
);
}
export default App;
// Root组件内容
export default ()=>{
return (
<div>
<Topbar/>
<Switch>
<Route exact path="/user" component={User}/>
<Route exact path="/" component={Home}/>
<Redirect to="/404" /> //注意应把<Redirect/>组件放在这里,不能放在App组件里,因为要跳转的组件也是“/”路由的子URL,会命中 <Route path="/" component={Root}/>而进入Root组件,不会匹配放在下面的<Redirect/>
<Switch>
</div>
);
}
通过该方法可以实现想要达到的目的(注意二级路由里要加<Switch>)。
4、注意
使用history.push(path)方法时,此history应从useHistory()获得(useHistory在react-router-dom包里导入),不能从createBrowserHistory()获得(createBrowserHistory是在history包里导入),否则会URL变更,但组件不更新。
5、总结
目前还是在学习中,因为也没到看源码之类的这种高级学习程度,搞不清楚具体是什么原因导致第一种方法不行。先记录下学习过程,因为忘的比较快,后面再试试。
--------------------------------除非注明,否则均为清风揽月阁原创文章,转载应以链接形式标明本文链接