欢迎,本笔记浅尝辄止,适用于初级开发
在个人网站的开发过程中,本着用新不用旧的理念尝试了Router4.0,踩了不少坑。看了很多大神的讲解,为便于个人理解和本着分享精神,有了这个文章。
开始之前,你要了解:
安装
以npm为例,进入你的项目根目录然后:
npm install react-router-dom --save
react-router-dom是react-router带有页面元素的版本,无需再安装react-router
引入
import {HashRouter, Route, Switch, Redirect} from 'react-router-dom';
配置
<HashRouter>{/*你也可以使用BrowserRouter*/}
<HadLogin>{/*所有页面最先渲染的组件*/}
<Switch>{/*如果一个组件下有多个child,必须使用Switch*/}
<Route path="/login" component={Login} />{/*Login要先import*/}
<Route path="/not-found" component={NotFound} />
<App>{/*渲染页面前先渲染的组件,如网站的菜单*/}
<Switch>
<Route exact path="/" component={ArticleList} />
<Route path="/article/:id" component={Article} />
<Route path="/games" component={Games} />
<Redirect from='*' to='/not-found' />
{/*路径检测按上下顺序执行,如果以上都没有检测到,则跳转到404*/}
</Switch>
</App>
</Switch>
</HadLogin>
</HashRouter>
再深入一级
如果还需要深入一层怎么办呢,比如games的子页面。之前的做法是将这种关系都体现在路由配置文件上,但是4.0做了较大改动,如果games想要有个child,则需要在他的页面中自己定义:
<div style={{width: 768,margin: '0 auto',textAlign: "center",paddingTop: 50}}>
<Switch>
<Route exact path="/games/ball" component={Ball} />
<Route path="/games/clock" component={Clock} />
<Redirect from='/games' to='/games/ball' />
</Switch>
{/*{this.props.children}*/}
<span>123</span>
</div>
并且,不需要this.props.children,子页面(组件)会在Switch的位置展现。
以这样的方式,页面可以有无限级,你可以尝试一下。
history哪去了
在之前的版本中,我们可以使用
import { hashHistory } from 'react-router';
进行自定义的页面跳转
但是在4.0版本以后,这种方法不再存在了,而是采用props方法。你必须使用
this.props.history.push(path)
但是,你会碰到一个问题,而且这个坑并不容易在官方文档中找到
只有在Route标签中引入的组件(页面)才有props.history
上文HadLogin、App等组件中,history是undefined
这可能是Router并没有对这些组件进行改造的原因。怎么办呢?
withRouter
通常情况下,我们会在页面底部用以下代码构建组件:
export default connect(mapStateToProps, mapDispatchToProps)(App);
如果你想让App这种包裹在外围的组件也拥有history,以便于push操作,你需要将以上改为:
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App));
这种情况下,shouldComponentUpdate会更新该组件,如果你不想让它被更新,则应使用:
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(App));
以上就是我在使用React-Router4.0中遇到的问题与解决办法。
如果有错误或更好的解决办法,请指正,也欢迎提问,谢谢。