React Router入门教程

React Router是个啥 ?

React Router是React的一个配套组件,正如其名,它是一个前端路由器。众所周知,正常的URL解析,并且返回相应的页面,应该是后端服务器的事情,但是,如果使用React了,就意味着前后端的分离,并且React Build出来的文件,到头来其实就只有一个index.html、一个js文件、一个css文件而已,这一个index.html就承载了整个站点的内容,从这个URL跳转到另外一个URL,对React来说,就只是组件的的重新渲染而已,而不是后端跳转。

所以React Router,其实作用就是根据给出URL的不同,渲染出不同的组件,只在前端实现,却能让页面装作后端跳转的样子。

开始之前

React Router当然是在React项目中使用的,如果还没有建立React项目,可以使用Facebook官方的create-react-app快速建立一个React项目,使用方法可以参照之前的博文:
使用create-react-app来创建react项目

在项目建立好之后,就使用npm或者yarn安装react-router吧:

// npm使用这条
npm install react-router-dom --save
// yarn使用这条
yarn add react-router-dom

接着我们可以把/src目录下的所有文件删除,因为我们根本就不需要用到它默认给的项目结构,我们按照自己的就好。接下将/public目录下的index.html修改一下,顺便在/src下新建一个index.js,留空备用

// /public/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>React Router Test</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>

React Router

0x01 BrowserRouter、HashRouter和Route

BrowserRouter和HashRouter这两个组件是路由器的最外层组件,所有的路由器子组件都应该被包裹在BrowserRouter和HashRouter中,这两者基本类似,区别在于BrowserRouter还支持后端跳转,而如果你的站点只需要展示静态文件,HashRouter会是很好的选择,不过为了保持项目的可扩展性,我们更加倾向于默认使用BrowserRouter来创建路由器。

Route则是用来描述URL和组件对应关系的子组件,我们使用Route组件来在路由器中创建URL和UI组件的对应关系。

下面给一个最简单的使用例子,修改index.js:

// /index.js

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

class Index extends React.Component {
    render() {
        return (
            <h1>Hello World!</h1>
        );
    }
}

class MainRouter extends React.Component {
    render() {
        return (
            <BrowserRouter>
                <Route exact path={'/'} component={Index}/>
            </BrowserRouter>
        );
    }
}

ReactDom.render(
    <MainRouter/>,
    document.getElementById('root')
);

这一段的意思就是,定义一个路由器组件MainRouter,它负责整个站点的路由,它会渲染一个BrowserRouter,其中定义了一条规则,如果URL完全匹配路径/,那么就渲染Index组件,渲染出来的结果当然是一个Hello World。

也就是说,在建站的时候,我们只需要把每一个网页的大组件写好,然后使用Route为每一个大页面组件创建一个URL的对应规则,就行了。

一个经典的Route长这样:

<Route exact path={'/location/location2'} component={ComponentName}>

其中path是你要匹配的URL,component是当URL匹配的时候,React应该渲染的组件,而exact,是可选的,指是否需要完全匹配path,如果该项不选的话,/location这一规则也能匹配到/location/123这样的URL

0x02 Switch

一个站点定义一条规则肯定是远远不够的,但是如果你尝试在一个BrowserRouter或者HashRouter中添加多个Route的话,它会给你报错,说一个Router中只能包含一条Route。

解决这一问题的办法就是在BrowserRouter和Route之间嵌套一层Switch,像这样:

<BrowserRouter>
    <Switch>
        <Route exact path={'/'} component={Index}/>
        <Route exact path={'/about'} component={About}/>
    </Switch>
</BrowserRouter>

众所周知,链接使用的是a标签,但是在React的前端世界中,使用a标签却不一定能让你到达指定位置,因为React页面的特殊性,React页面是以组件和渲染作为单位,而不是真实存在的网页文件,这样的话,a标签可能无法发挥作用,再者a标签会导致页面的刷新,对于全部文件一起打包的React来说,这太伤了,取而代之,在React的路由系统中,应该使用Link,像这样

<Link to={'/'}>jump to index</Link>

0x04 URL参数

有些情况,我们需要使用到URL传参,这在React Router中也有着对应的实现方法,举一个例子:

// /index.js

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

class Index extends React.Component {
    constructor() {
        super();
    }

    render() {
        return (
            <div>
                <h1>Hello, { this.props.match.params.name }</h1>
            </div>
        );
    }
}

class MainRouter extends React.Component {
    render() {
        return (
            <BrowserRouter>
                <Route exact path={'/:name'} component={Index}/>
            </BrowserRouter>
        );
    }
}

ReactDom.render(
    <MainRouter/>,
    document.getElementById('root')
);

只要在Route的path中使用:key的形式就可以将内容以props的形式传入被渲染的组件,并且在组件内部可以被以例子中的形式使用

break;

学到这里,React Router的基本用法就差不多了,基本能够满足日常撸前端的需求了,当然,React Router还有一些值得探索的特性,你可以直接参考官方API来更深入地学习:
React Router