react-router v3学习笔记

卞琨
2023-12-01

最近接手了一个简单的项目,需要修改一些逻辑,时间也比较充裕,正好适合我这个小白边学边做。其中涉及了一些知识点,包括redux和router。所以今天先开始学习阮一峰大神的react router教程
看完这篇文章之后才知道react-router v4和v3有很大区别。在v4里面主要引用react-router-dom获得组件。

一、基本用法:

import { Router, Route, hashHistory } from 'react-router';

render((
  <Router history={hashHistory}>
    <Route path="/" component={App}/>
    <Route path="/repos" component={Repos}/>
  	<Route path="/about" component={About}/>
  </Router>
), document.getElementById('app'));

以上代码用户访问http://www.example.com/,实际会看到的是http://www.example.com/#/,访问的是App组件;用户访问/repos(比如http://localhost:8080/#/repos)时,加载Repos组件;访问/about(http://localhost:8080/#/about)时,加载About组件。

hashHistory 是一种路由的类型,但是有#,一般大家都不倾向于用这个。

二、嵌套路由

<Router history={hashHistory}>
  <Route path="/" component={App}>
    <Route path="/repos" component={Repos}/>
    <Route path="/about" component={About}/>
  </Route>
</Router>

上面代码中,用户访问/repos时,会先加载App组件,然后在它的内部再加载Repos组件。

一般用在通过左侧的菜单切换视图的情况里吧。App组件需要用this.props.children 把子路由传进去。

let routes = <Route path="/" component={App}>
  <Route path="/repos" component={Repos}/>
  <Route path="/about" component={About}/>
</Route>;

<Router routes={routes} history={browserHistory}/>

还可以将路由通过属性方式传给Router组件。

三、path使用通配符

(暂时用不上,先不看了)
不以 / 开头的表示相对路径,匹配时会相对于父组件的路径。
需要注意的是,路由的匹配规则是从上到下,如果上一条匹配上了,下一条就不会匹配。

<Route path="/comments" ... />
<Route path="/comments" ... />

这个只会匹配第一个组件

<Router>
  <Route path="/:userName/:id" component={UserPage}/>
  <Route path="/about/me" component={About}/>
</Router>

这个只会匹配第一个,所以一般带参数的应该放在最后,可以当作默认组件来理解,一般默认的就是放在最后的。

四、IndexRoute 组件

<Router>
  <Route path="/" component={App}>
    <Route path="accounts" component={Accounts}/>
    <Route path="statements" component={Statements}/>
  </Route>
</Router>

以上代码当访问根路径/ 时,不会加载任何子组件,相当于只加载了一个空壳子。

<Router>
  <Route path="/" component={App}>
    <IndexRoute component={Home}/>
    <Route path="accounts" component={Accounts}/>
    <Route path="statements" component={Statements}/>
  </Route>
</Router>

所以使用IndexRoute指定 ,访问根目录/时的的默认子组件为Home。
注意:IndexRoute组件没有路径参数path.

五、Redirect组件

<Route path="inbox" component={Inbox}>
  {/* 从 /inbox/messages/:id 跳转到 /messages/:id */}
  <Redirect from="messages/:id" to="/messages/:id" />
</Route>

messages/:id 是相对路径,/messages/:id 是绝对路径。
现在访问/inbox/messages/5,会自动跳转到/messages/5。

六、IndexRedirect 组件


<Route path="/" component={App}>
  <IndexRedirect to="/welcome" />
  <Route path="welcome" component={Welcome} />
  <Route path="about" component={About} />
</Route>

七、在页面内实现路由的跳转

  1. Link/IndexLink
render() {
  return <div>
    <ul role="nav">
      <li><Link to="/about">About</Link></li>
      <li><Link to="/repos">Repos</Link></li>
    </ul>
  </div>
}

Link 就是 <a>元素的React版本。
如果链接到根路由用 IndexLink。因为用Link的时候使用 / 会匹配到任何子路由,IndexLink会精确匹配 /。
使用activeStyle ,activeClassName 可以修改当前路由的样式。(还没试过不知道好不好用)
使用Link组件的时候踩过一个坑,就是当Router和Route组件之间有自定义的组件时,使用Link会只更新url, 不更新组件。解决办法是用withRouter包裹该自定义组件。
类似于这样:

var Home =  withRouter (connect()(() => <Link to={"Cal"}>Home 点击到子页面
</Link>))

具体参考链接https://blog.csdn.net/isaisai/article/details/78088823
2. History API

import { browserHistory } from 'react-router';
browserHistory.push('/some/path');

这个有坑,直接用的时候 url 变化了,组件没有刷新不知道为啥。

八、history属性

应该还记得最开始给Router传的那个history属性吧,当时传了一个hashHistory 属性给它。除了这个属性,还有别的属性:
browserHistory和createMemoryhistory。

hashHistory 的表现形式很明显,就是有一个# ,看上去很不美观。所以倾向于使用browserHistory, 这个就是背后调用了浏览器的History API。但是这个情况需要对服务器改造,否则用户直接向服务器请求子路由会显示网页找不到的404错误???这个怎么办我也不知道。createMemoryHistory是个啥,我也不知道!!!

九、路由的钩子

每个路由都有钩子,用户进入或离开的时候触发。

<Route path="about" component={About} />
<Route path="inbox" component={Inbox}>
  <Redirect from="messages/:id" to="/messages/:id" />
</Route>

上面的代码中,如果用户离开/messages/:id,进入/about时,会依次触发以下的钩子。

  • /messages/:id的onLeave
  • /inbox的onLeave
  • /about的onEnter

使用场景:

  1. 当用户进入某个页面的时候需要做验证。
  2. 当用户离开某个页面的时候弹出对话框,让用户确认是否离开。

十、和Redux
v4: 以前react-router-redux里创建浏览器历史对象的方法也没有了,需要直接导入history这个npm。

 类似资料: