react-router 4.x(路由)

一、react-router


1.安装

npm install react-router-dom --save

2.使用,我们直接上菜,想必大家已经饿了。

//index.js
import "../css/reset.css";
import "../css/common.css";
import React,{ Component } from "react";
import { render } from "react-dom";
import {
    BrowserRouter as Router,
    Route,
    Link
}from 'react-router-dom';
import App from "../Components/app";
import Shop from "../Components/shop.js";
import Owner from "../Components/owner.js";

class Hello extends Component{
    render(){
        return (
            <Router>
                <div>
                    <ul>                        //进行路由跳转
                        <li><Link to="/">App</Link></li>
                        <li><Link to="/shop">Shop</Link></li>
                    </ul>                    //设置跳转的路径 
                    <Route exact path="/" component={App} />
                    <Route path="/shop" component={Shop} />
                    <Route path="/owner" component={Owner} />
                </div>
            </Router>
        )
    }
}
render(
    <Hello />,
    document.getElementById('root')
)


和之前的版本一样,Router还是一个容器,但他的角色却改变了,4.0的react-router可以任意的放标签了,这意味着使用方式的改变,但真正的路由通过Route定义。Link标签依然可以看作a标签。点击会改变浏览器Url的hash值,通过Route标签来捕获这个url并返回component属性中定义的组件。Route标签内有个exact关键字,它是用来将”/”做唯一的匹配。如果没有这个的话,在匹配其他的同时也会匹配到当前。一试便知。 
通过Router路由的组件可以拿到一个match参数,这个参数是一个对象。其中包含几个数据: 
isExact: 刚才已经说过这个关键字,表示是为做全等匹配。 
params: path中包含的一些额外数据。 
path: Route组件path属性的值。 
url: 实际url的hash值。 
3.Router标签


hashHistory    老版本浏览器的history
browserHistory h5的history
memoryHistory node环境下的history,存储在memory中。

4.Route标签 
在例子中你可能注意到了Route的几个prop

exact
path
component
render

他们都不是必填项,如果path没有赋值,那么此Route就是默认渲染的。 
Route的作用就是当url和Route中path属性的值匹配时,就渲染component中的组件或者render中的内容。

说到这,那么Route内部是怎样实现这个机制的呢,不难猜测肯定是用一个匹配的方法来实现的,那么Router是怎么知道url更新了然后重新进行匹配并且渲染呢? 
整理一下思路,在一个web应用中,改变一个url无非两种方式。一种是利用超链接进行跳转,另一种是使用浏览器的前进后退功能,前者在触发Link的跳转事件之后再触发。后者是Route利用的history的listen方法来监听url的变化。为了防止引入新的库,Route创作者选择使用html5中的popState事件。只要点击了浏览器的前景或者后退按钮,这个事件就会触发,我们来看一下Route的代码。

class Route extends Component {
  static propTypes: {
    path: PropTypes.string,
    exact: PropTypes.bool,
    component: PropTypes.func,
    render: PropTypes.func,
  }

  componentWillMount() {
    addEventListener("popstate", this.handlePop)
  }

  componentWillUnmount() {
    removeEventListener("popstate", this.handlePop)
  }

  handlePop = () => {
    this.forceUpdate()
  }

  render() {
    const {
      path,
      exact,
      component,
      render,
    } = this.props

    //location是一个全局变量
    const match = matchPath(location.pathname, { path, exact })

    return (
      //有趣的是从这里我们可以看出各属性渲染的优先级,component第一
      component ? (
        match ? React.createElement(component, props) : null
      ) : render ? ( // render prop is next, only called if there's a match
        match ? render(props) : null
      ) : children ? ( // children come last, always called
        typeof children === 'function' ? (
          children(props)
        ) : !Array.isArray(children) || children.length ? ( // Preact defaults to empty children array
          React.Children.only(children)
        ) : (
              null
            )
      ) : (
              null
            )
    )
  }
}

Route在组件将要Mount的时候,添加popState事件的监听,每当popState事件触发,就使用forceUpdate强制刷新,从而基于当前的location.pathname进行一次匹配。再根据结果渲染。

  componentWillMount() {
    addEventListener("popstate", this.handlePop)
  }
  handlePop = () => {
    this.forceUpdate()
  }

2.路由功能

2.1用到的路由库

import { Router, Route, IndexRoute } from 'react-router'  

2.2路由跳转

 <Link to="/list">to list</Link>  

2.3路由视图

<Route path="/about" component={About}/>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值