React Router V5 使用总结

1、先简单交代几句

对于以前没有接触过 React Router 的同窗来讲,必定要注意:最新的React Router版本是 V5 。除此以外,还有 V2 V3 V4 版本。其中V4和V5版本的用法和理念基本上是一致的,可是和以前的V二、V3版本有较大差别。css

因此在学习以前必定要弄清楚本身使用的是哪个版本,若是是V4或者V5,V4和V5两个版本的文档笔记均可以参考;若是你用的是V2或者V3,那么必定要找到对应的文档笔记。react

在我学习React Router的时候,使用的是V5,因此这篇笔记也是对 React Router V5 的一些总结。若是你是一名React小白,我想经过这篇笔记,你能够基本会使用React Router。若是你想更深层次地理解React Router,能够访问:reacttraining.com/react-route…webpack

2、React Router 的基本使用

1. 安装

在V4和V5版本中,React Router分红了两个大的方向:React Web Router 和 React Native Router 。若是你是建立的React Web应用,就使用React Web Router ,这里咱们使用的就是这个Router,因此执行如下命令进行安装:web

npm install --save react-router-dom
复制代码

2. 在React项目中配置路由

想要在React项目中使用路由,必不可少的有两个组件(component): BrowserRouterRoute 。在React项目中,经过如下命令引入这两个组件:shell

import { BrowserRouter, Route } from "react-router-dom";
复制代码

BrowserRouter 组件是React Router的核心,Route组件是React Router的具体配置。举个例子来讲:BrowserRouter 组件就像是一个文具盒,Route组件就像是一件件文具同样,须要放在这个盒子里。这样咱们在使用文具的时候,只须要打开文具盒,从里面取出便可。npm

了解了这层关系,咱们就能够在React中配置路由了,配置很是简单,示例代码以下:浏览器

// React 应用中的 App.js 文件

import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom'
import Set from './views/set/Set'
import Help from './views/help/Help'

class App extends React.Component {
    render() {
        return (
            <BrowserRouter>
                <Route path="/help" component={Help} />
                <Route path="/set" component={Set} />
            </BrowserRouter>
        );
    }
}

export default App;
复制代码

在App.js文件中配置完车以后,而后在React入口文件中(通常是index.js文件),引入App.js文件并挂载到页面上,示例代码以下:服务器

// React 应用中的入口文件 index.js 

import React from 'react'
import { render } from 'react-dom'
import App from './App'

render((
   <App /> ), document.getElementById('root')) 复制代码

挂载完成以后,经过npm run start 等命令启动本地开发服务器,就能够经过路由访问咱们的React项目了。实例以下:react-router

简单介绍一下以上代码中的路由配置规则,以这条路由配置为例:dom

<Route path="/help" component={Help} />
复制代码

Help 是咱们以前定义好的一个React组件,该组件的定义代码以下:

import React, { Component } from 'react'

class Help extends Component {
    render() {
        return (
            <div className="help-box"> 帮助与反馈 - 页面 </div>
        );
    }
}

export default Help;
复制代码

当咱们在浏览器地址栏中输入 http://localhost:3000/help 的时候,React Router 会匹配到 <Route path="/help" component={Help} /> 这一条记录,而后就会在当前位置渲染对应的component。

注意是当前位置,说得更通俗一点:就是使用将Help组件中的代码替换掉 <Route path="/help" component={Help} /> 代码,进而渲染出路由对应的component。关于这一点,后面会有更详细的解释。

3. 在React中经过连接跳转路由

经过上面的配置,咱们已经能够经过输入URL来跳转路由,可是更多状况下,咱们但愿能够经过点击页面上的连接进行路由的跳转,好比如下的示例:

想要实现这一点,咱们只须要引入 Link 这个组件便可,具体代码以下:

// React 应用中的 App.js 文件

import React from 'react';
import { BrowserRouter, Route, Link } from 'react-router-dom'   // 引入 Link 组件
import Set from './views/set/Set'
import Help from './views/help/Help'

class App extends React.Component {
    render() {
        return (
            <BrowserRouter>
            	{/* 注意 Link 组件必定要位于 BrowserRouter 组件中 */}
                <ul>
                    <li><Link to="/help">Help</Link></li>
                    <li><Link to="/set">Set</Link></li>
                </ul>
                
                <Route path="/help" component={Help} />
                <Route path="/set" component={Set} />
            </BrowserRouter>
        );
    }
}

export default App;
复制代码

3、React Router 的进阶使用

如今咱们已经掌握了React Router的基本使用,可是这个时候咱们掌握的知识还不足以让咱们熟练地使用它,因此下面为你们介绍React Router更多内容。

1. Route 的匹配规则

在对Route进行配置的时候,咱们能够传如下参数:path、exact、component、render、children 。这些参数都不是必须的,也就是说,咱们有不少中配置Route的方式,常见的有如下几种:

<BrowserRouter>
    <Route component={Wallet} />
    <Route path="/" component={Index} />
    <Route exact path="/" component={Index} />
    <Route path="/help" component={Help} />
    <Route path="/render" render={ () => { return <h1>我是匹配到的路由</h1> } } />
</BrowserRouter>
复制代码

这里分别介绍以上五种Route的配置方式:

  • <Route component={Wallet} />

    在配置Route的时候没有指定 path 属性,这时只要你打开项目,不管你访问什么路径,这个Route都会匹配到。

  • <Route path="/" component={Index} />

    配置Route的时候,指定 path="/" ,和上面配置的效果同样,只要你打开项目,不管你访问什么路径,这个Route都会匹配到。这种配置方式咱们成为 "非严格匹配" ,你在项目中访问的任何一个路径,里面都会包含path="/" 的路径。因此不管访问什么路径,这个Route都会匹配到。

  • <Route exact path="/" component={Index} />

    和上面一条的配置方式不一样,这里在配置Route的时候,传入了 exact 属性,说明这个配置方式是 "严格匹配" ,只有当咱们访问项目的根路径的时候,才会匹配到这个Route。好比:localhost:3000/ 。

  • <Route path="/help" component={Help} />

    一条很常规的Route配置方式,当咱们访问"/help"路径的时候,匹配到这个Route,进而渲染出对应的component。

  • <Route path="/render" render={ () => { return <h1>我是匹配到的路由</h1> } } />

    和上一条路由配置不一样的是,这里没有component属性,而是换成了render属性。该属性是一个函数,当匹配到这个Route的时候,页面将会渲染出这个函数返回的内容。

2. Switch 组件的使用

Switch组件的使用其实很是简单,举个例子:若是说BrowserRouter组件是一个大的文具盒的话,那么Switch组件就是这个大文具盒中的一个小袋子,Route组件就是这个小袋子中的一支铅笔,咱们须要铅笔的时候,直接从这个小袋子里面取出一支便可。注意:是最多只能取出一支铅笔。

也就是说,当进行路由匹配的时候,一旦匹配到了Switch组件中的一个Route,那么就不会再继续匹配。好比如下实例:

<BrowserRouter>
    <Switch>
        <Route component={Wallet} />
        <Route path="/" component={Index} />
        <Route path="/help" component={Help} />
        <Route path="/render" render={() => { return <h1>我是匹配到的路由</h1> }} />
    </Switch>
</BrowserRouter>
复制代码

若是咱们访问 "localhost:3000/help" 路径,虽然前三个Route都匹配,可是页面只会渲染第一个匹配到的Route,其余的都被忽略。看到这里你可能会问,这个组件有什么做用呢?能够在如下场景中发挥做用:若是当前路径没有匹配到任何Route的时候,路由跳转到 404 页面,那么就能够这样写:

<BrowserRouter>
    <Switch>
        <Route path="/set" component={Set} />
        <Route path="/help" component={Help} />
        <Route path="/render" render={() => { return <h1>我是匹配到的路由</h1> }} />
        <Route component={NotFound} />
    </Switch>
</BrowserRouter>
复制代码

经过上面的配置,若是当前路径有匹配到最后一个以外的Route,那么就显示对应内容,再也不继续匹配;若是没有匹配到最后一个以外的Route,就显示最后一个Route,由于这个Route能够匹配任何路径。能够把这个Route对应到 404 页面。

3. 匹配到的 Route 如何渲染内容

前面讲述了Route的配置和匹配规则,下面咱们讲述一下,当路径匹配到Route以后,会如何渲染对应的内容。

以前有提到过:是在 当前位置 渲染内容,对于一些刚入门的小白来讲,可能不能马上理解当前位置是什么位置。因此咱们举个例子,好比咱们在项目的App.js组件中有如下配置代码:

class App extends React.Component {
    render() {
        return (
            <div className="content">
                <BrowserRouter>
                    <Route exact path="/" component={Index} />       {/* 位置 A */}
                    <Route path="/help" component={Help} />          {/* 位置 B */}
                    <Route path="/set" component={Set} />            {/* 位置 C */}
                </BrowserRouter>
            </div>
        );
    }
}
复制代码

那么当路径为 "help" 的时候,就会匹配到第二个Route,那么React Router就会在 位置B 对应的这一行将 Route 组件替换成Help组件;而其余没有匹配到的Route,会被替换成null,至关于将这些 Route 组件直接删去。最终的结果如如下代码所示:

// Help 组件的定义代码能够在上文中找到
class App extends React.Component {
    render() {
        return (
            <div className="content"> <div className="help-box"> 帮助与反馈 - 页面 </div> </div>
        );
    }
}
复制代码

之因此讲这么一个知识点,是为后面介绍如何配置嵌套路由作准备,这里能够先提一下:若是咱们想在 组件A中 嵌套几个子路由,那么就能够将这几个Route配置,写到组件A中,一旦路径匹配到了这些Route,就会在组件A中对应的位置渲染子路由对应的组件。听不懂不要紧,后面会有详细的解释。

4. 对 React Router 的一点解释

经过上面的笔记,你可能会认为:Route组件必须位于BrowserRouter组件中,且两个组件必须在同一个文件中。

其实否则,从代码结构上说,Route组件确实必须位于BrowserRouter组件中,可是两个组件不必定非要在一个文件中,只要打包编译以后,两个组件知足Route组件位于BrowserRouter组件中就能够。好比如下的写法也是彻底正确的:

// 项目的入口文件 index.js
import React from 'react'
import { render } from 'react-dom'
import App from './App'
import { BrowserRouter } from 'react-router-dom'

render((
   <BrowserRouter> <App /> </BrowserRouter>
), document.getElementById('root'))
复制代码
// App.js 文件
import React from 'react';
import { Route, NavLink } from 'react-router-dom'
import Set from './views/set/Set'
import Help from './views/help/Help'
import Index from './views/index/Index'
import Wallet from './views/wallet/Wallet'

class App extends React.Component {
    render() {
        return (
            {/* 注意这里已经没有了 BrowserRouter 组件 */}
            <div className="content">
                <ul>
                    <NavLink activeClassName="selected" to="help">help</NavLink >
                    <NavLink activeClassName="selected" to="index">index</NavLink >
                    <NavLink activeClassName="selected" to="wallet">wallet</NavLink >
                    <NavLink activeClassName="selected" to="set">set</NavLink >
                </ul>

                <Route path="/help" component={Help} />
                <Route path="/index" component={Index} />
                <Route path="/wallet" component={Wallet} />
                <Route path="/set" component={Set} />
            </div>
        );
    }
}

export default App;
复制代码

5. 如何配置嵌套路由

嵌套路由,顾名思义就是在一个主路由匹配到的页面中再配置一些路由,咱们如今就来说述如下如何使用 React Router 配置嵌套路由,配置完成以后,咱们会看到如下效果:

在以前的基础之上,咱们已经配置好了一级路由,便可以通关点击 set 按钮跳转到匹配到的Route对应的组件中,即Set组件,具体配置能够参考上一个代码块中的代码。

下面咱们要作的就是在Set组件中,进行配置二级路由,即嵌套路由。配置很是简单,这里先直接给出代码:

import React, { Component } from 'react'
import { Route, Link } from 'react-router-dom'
import SetSystem from '../SetSystem'
import SetPerson from '../SetPerson'
import SetTime from '../SetTime'
import './Set.scss'

class Set extends Component {
    componentDidMount() {
        // 当前页面匹配到的路径,这里是"/set"
        // 使用这个路径,配置Route和Link
        console.log(this.props.match.path);
    }

    render() {
        return (
            <div className="set-box">
                我的设置 - 页面

                <div className="link-list">
                    <Link to={`${this.props.match.path}/system`}>system</Link>
                    <Link to={`${this.props.match.path}/person`}>person</Link>
                    <Link to={`${this.props.match.path}/time`}>time</Link>
                </div>

                <div className="child-router">
                    <Route path={`${this.props.match.path}/system`} component={SetSystem} />
                    <Route path={`${this.props.match.path}/person`} component={SetPerson} />
                    <Route path={`${this.props.match.path}/time`} component={SetTime} />
                </div>
            </div>
        );
    }
}

export default Set;
复制代码

注意代码中咱们引入了 Set.scss 样式文件,给页面元素添加一些很是简单的样式,具体样式你能够自定义,这里的示例代码以下:

.set-box {
    .link-list {
        a {
            margin: 0px 10px;
        }
    }
}
复制代码

代码书写完成以后,咱们就配置好了嵌套路由,启动项目你就能够看到上面GIF中展现的效果。这里对上面的配置作简单的解释:

首先再提一下:匹配到的Route会在 当前位置 渲染匹配到的内容(这个内容多是component组件,render函数返回的结果等)。

就是由于React Router的这个特性,咱们才能配置嵌套路由,不然,及时匹配到了Route,可是咱们不知道它的渲染位置,也不能实现此功能。

其次再说一下 this.props.match 这个属性,经过这个属性,咱们能够得到当前页面,即一级路由匹配到的组件对应的路径,在这里 this.props.match 的值是 "/set"。

了解了这一点,咱们就能够在 this.props.match 的帮助下,设置二级路由的路径。因此如下两种写法是等价的,可是第一种写法更加灵活:

{/* 第一种写法 */}
<Link to={`${this.props.match.path}/system`}>system</Link>
<Route path={`${this.props.match.path}/system`} component={SetSystem} />

{/* 第二种写法 */}
<Link to="/set/system">system</Link>
<Route path="/set/system" component={SetSystem} />
复制代码

最后再再说一下 Route组件BrowserRouter组件 的位置问题。初次接触React Router的小白可能会问:在设置嵌套路由的时候,Route组件怎么没有包含在BrowserRouter组件中?

事实上,在使用webpack将代码打包打包编译以后,Route组件已经包含在BrowserRouter组件中了。在代码层面咱们能够这样理解:Route组件包含于Set组件中,Set组件包含于App组件中,App组件包含在BrowserRouter中。因此Route组件已经包含在BrowserRouter组件中。

4、写在最后

啰啰嗦嗦写完了对React Router的总结,内容挺多可是都很基础,但愿能够帮到刚刚入门的小白。

若是大神们看到错误之处,还但愿各位能及时指正。

相关文章
相关标签/搜索