react-router 4

简介

在web开发中,前端扮演着越来越重要的角色。路由功能可以由前端来实现,无需后端返回页面,通过前端路由实现URL的改变以及对页面的切换。较早之前实现前端路由的方法,在Angular1中时通过hash(#)来处理,也就是带#号的锚点。前端路由多种多样,我们还可以通过操作DOM的histroy对象,使用history.pushState,window.onpopstate这2个方法来实现。

前端路由主要实现2个部分的功能:

  • 改变当前 URL 地址
  • 更具 URL 地址对当前页面进行切换
<ul>
    <li><a href="/home">Home</a></li>
    <li><a href="/blog">Blog</a></li>
    <li><a href="/about">About</a></li>
</ul>
<h2>History state:</h2>
<p id="state"></p>
// 修改 history pushState
(function(history){
  var pushState = history.pushState;
  history.pushState = function(state) {
    if (typeof history.onpushstate == "function") {
      history.onpushstate({state: state});
    }
    return pushState.apply(history, arguments);
  }
})(window.history);

// 添加触发事件
window.onpopstate = history.onpushstate = function(event) {
  document.getElementById('state').innerHTML = "location: " + document.location + ", state: " + JSON.stringify(event.state);
}

// 为链接绑定事件处理函数,阻止页面跳转,触发pushState
var links = document.getElementsByTagName('a');
for(var i = 0; i < links.length; i++) {
  links[i].onclick = function (event) {
    event.preventDefault();
    var route = event.target.getAttribute('href');
    history.pushState({page: route}, route, route);
    console.log('current state', history.state)
  }
}

react-router 为我们提供预制的,可以实现功能的组件,使用方法和 react 组件保持一致,只需要我们在应用的时候加上一些JSX的标签。react-router 目前已出了4个版本,而且不同版本直接差异也比较大。目前4.0版本中包含三个主要的库:

  • react-router-dom(web)
  • react-router-native(rn)
  • react-router(core)

react-router-dom 和 react-router-native 相当于在 react-router 之上又封装了一层。让我们来关注并且手动配置的部分更少了,一般如果开发web应用的话,react-router-dom 就足够了。

我们从 react-router-dom 中引入三个组件,BroswerRouter、Router、Link,这个组件都是 react 组件。

  1. 首先把BrowswerRouter放到最外层,这是给我们应用添加路由功能的容器组件
  2. 之后在我们觉得合适的地方添加link组件,link组件的to属性就是对应路由的地址
  3. 最后使用Router来添加正式的路由。每个Router的path属性也是对应路由的地址,点击对应的link,就会跳转到对应的路由中。

Router 的 component 属性,就是路由跳转过来显示的组件。

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route, Link } from 'react-router-dom'

const BasicExample = () => (
  <BrowserRouter>
    <div>
      <ul>
        <li><Link to="/">Home</Link></li>
        <li><Link to="/about">About</Link></li>
        <li><Link to="/topics">Topics</Link></li>
      </ul>
      <Route exact path="/" component={Home}/>
      <Route exact path="/about" component={About}/>
      <Route exact path="/topics" component={Topics}/>
    </div>
  </BrowserRouter>
)

const Home = () => (
  <div><h2>Home</h2></div>
)

const About = () => (
  <div><h2>About</h2></div>
)

const Topics = ({ match }) => {
  return <div><h2>Topics{match.url}</h2></div>
}

ReactDOM.render(<BasicExample />, document.getElementById('root'))

相关配置

  • BrowserRouter 主要实现页面功能与URL同步的功能,新版本的BrowserRouter内置对浏览器histroy的支持,不需要我们做任何的配置就可以正常使用,并且没有#号,也不会生成随机字符串。

  • Route

Route是路由组件,一般接受2个参数,path 和 component,用来制定路由的URL已经所要渲染的组件。exact 属性,添加后只会匹配到path的根地址。

  • Link

Link 是最基本的导航连接组件,我们只需要使用 to 参数,指向我们要使用的路由即可。在我们使用当中,会经常为我们的导航使用不同的样式,这就需要使用的 NavLink,并加上导航使用的激活属性 activeStyle。组件接收 match 对象包含以下几项属性:

  • params 预设url中传递的参数
  • isExact 当前url是否绝对匹配此路由
  • path 路由设定的path值
  • url 当前url地址

除了通过组件的参数获取外,还可以通过 withRouter 方法来获取

const Title = ({match}) => (
  <h1>{match.params.repo}</h1>
)
Title = withRouter(Title)