React-Router自学指北

198 阅读7分钟

前置知识

SPA应用

在了解Router之前,我们需要知道的前置知识是SPA应用,它的全称为single Page Application,全名为单页面应用,即基本所有功能都在一个页面完成。

与它做对比的就是传统的a标签页面,由于传统的a标签页面每次点击都会给服务器发送指令,通过服务器返回让用户界面进行资源加载,这种方式受网速影响较大,且对于服务器来说大量的数据传输转发都会造成一定压力,种种因素造成用户的体验感不是很好。

单页面应用的诞生对于上面的问题有着明显的改善,比如说我们把一个页面都一次性发送给用户,然后随着用户的点击来切换不同的内容,对于用户来说刷新的速度非常快。

SPA原理

这里只总体介绍一下,如果对原理更感兴趣,可以参考我写的这篇深入理解前端路由

hash模式

SPA一开始是使用hashChange事件来完成的,基本原理就是通过url中hash的改变来响应不同的页面,实际上就是通过获取#后面的字符,通过hash与dom的映射关系来让不同的页面展示出来,这叫hash模式

history模式

由于HTML5出来后新增了pushState事件,我们可以往history上使用这个,就可以把url给改掉而不刷新页面,这就可以拿到对应的路径,再通过path和dom的映射关系把不同的页面展示出来,这叫history模式

memory模式

上面两种都是通过对url栏的修改形成与页面之间的对应关系来实现的,memory模式是使用localstorage把字符存进去,这个跟url栏就没有一点关系了,适合只有一个url的情况下使用。

一般我们开发的时候会使用hash模式,生产模式会使用history模式。因为history模式对seo更友好,百度爬虫会收录/之后的东西,而忽略#后面的东西。

hash模式适合开发的原因是#不会向服务器发送请求,都是浏览器自己完成,而/的方式如果调试时刷新了页面,就会向后端发送请求,就会需要后端首先配置好response内容。

Router

Router翻译过来就是路由器,它的作用就是帮助分发请求,实现请求与页面相对应的展示效果。

Router的目的就是帮助前端人员更好地规划路由展示效果,开发SPA应用。

React-Router是React团队研发出来协助React程序员开发项目时,提前写好API方便使用的一个库,我们目前就要学习如何使用它。

Router基本使用

安装

yarn add react-router-dom

基本概念

目前的版本中React-Router提供三大组件

  • Router是所有路由组件共用的底层接口组件,它是路由规则制定的最外层的容器。你可以叫他为路由器
  • Route路由规则匹配,并显示当前的规则对应的组件。你可以叫他路由匹配器
  • Link路由跳转的组件,你可以叫他导航

其中Router组件针对不同的功能和平台有以下子组件

  • <BrowserRouter> 浏览器的路由组件
  • <HashRouter> URL格式为Hash路由组件
  • <MemoryRouter> 内存路由组件
  • <NativeRouter> Native的路由组件
  • <StaticRouter> 地址不改变的静态路由组件 Router就是个容器,所有路由操作都要在Router里面,

Route是用来做路由规则的,它定义的是路径和显示组件之间的对应关系

Link就是a标签,实现声明式的跳转

下面通过实例来理解,请手动使用create-react-app打好手脚架,再把我的代码放入App.js文件中。

创建一个Router组件

import { BrowserRouter as Router, Link, Route } from "react-router-dom";
import "./App.css";
const Home = () => (
  <div>
    <h2>Home</h2>
  </div>
);
const About = () => (
  <div>
    <h2>About</h2>
  </div>
);
const Product = () => (
  <div>
    <h2>Product</h2>
  </div>
);
function App() {
  return (
    <Router>
      <div className="App">
        <Link to="/">Home</Link>
        <hr />
        <Link to="/About">About</Link>
        <hr />
        <Link to="/Product">Product</Link>
        <hr />
        <Route path="/" exact component={Home}></Route>
        <Route path="/about" component={About}></Route>
        <Route path="/product" component={Product}></Route>
      </div>
    </Router>
  );
}
export default App;

说明

import { BrowserRouter as Router, Route, Link } from 'react-router-dom' 1、上面的引入方式是把BrowserRouter、Route、Link引入进来,然后给BrowserRouter取一个别名Router,这样有个好处,以后我如果想换掉BrowserRouter只需要一行代码。

2、可以看到我在App函数中,使用Router将所有内容都包裹起来了,然后在<Route>标签内写入path='/' exact component={Home}意思是当我的路径是/时,渲染Home组件,exact是准确、精确的意思,表示准确匹配,它是Route的属性。

如果你使用yarn start来查看页面,就会看到这样的画面,试着点点看

好了,你已经初步了解Router了。下面我们来了解一下主要的API

Router组件

上面我们说原理的时候说过,有使用hash的Hash模式,有使用pushState的history模式,React自然也给了我们选择,分别是对应history模式的BrowserRouter和对应Hash模式的HashRouter。

这两个都是顶级组件,直接定义使用什么模式,反正开发用Hash、生产用history,我想你已经会选了。

属性

  • basename: 字符串类型,路由器的默认根路径
  • forceRefresh: 布尔类型,在导航的过程中整个页面是否刷新
  • getUserConfirmation: 函数类型,当导航需要确认时执行的函数。默认是:window.confirm
  • keyLength: 数字类型location.key 的长度。默认是 6

basename

基准url的名称,比如说我们有个二级子目录admin,我需要把应用放到这个模块下,如果不带这个basename,那我有可能写三四遍link to='/admin/xxx',现在我只需要写一遍,就像这样

<Router basename="/admin"> 
      <div className="App">
        <Link to="/">Home</Link>
        <hr />
        <Link to="/About">About</Link>
        <hr />
        <Link to="/Product">Product</Link>
        <hr />
        <Route path="/" exact component={Home}></Route>
        <Route path="/about" component={About}></Route>
        <Route path="/product" component={Product}></Route>

forceRefresh:bool

当设置为true时,在导航的过程中整个页面会刷新。

Link组件

Link组件就是解析前的a标签

to属性

通过to属性来指明目标,to属性可以直接指明一个字符串,也可以指明一个对象表示我要跳转这个路径或者地址

 <Link
          to={{
            pathname: "/about",
            search: "?key=name",
            hash: "#hash",
            state: { fromDashboard: true },
          }}
        >
          About
        </Link>

replace:bool

默认为false,当设置为 true的时候,会替换掉历史记录的原地址。

NavLink组件

NavLink是一个特殊版本的Link,可以使用activeClassName来设置Link被选中时被附加的class,使用activeStyle来配置被选中时应用的样式。此外,还有一个exact属性,此属性要求location完全匹配才会附加class和style。这里说的匹配是指地址栏中的URl和这个Link的to指定的location相匹配。

属性

  • to:跟Link组件一样
  • exact:精准匹配,所有单单指向/的都要用这个,不然会匹配到一切带/的路径,例如/a,这样就不准确。
  • activeClassName:选中后添加class属性
  • activeStyle:选中后添加style
<NavLink activeClassName="selected" to="/About">
          About
        </NavLink>

上面的代码,如果用户选中这个连接,那么就会加上class属性。

Route组件

Route组件是用来定路径与组件的对应关系的,是react-Router中最重要的组件。

先来说说Route的三种渲染方式

1、component:渲染组件

2、render:这里写function,这个可以用来加一些逻辑,Route会渲染function的返回值,实际上就是允许你写组件

        <Route
          path="/"
          exact
          render={(props) => {
          console.log(props)
            if (1 > 2) {
              return <Home />;
            }
          }}
        ></Route>

注意这里的props,会记录history、location等参数

3、children:跟render类似语法,但是多了一个参数match,并且不管怎样都会渲染

switch组件

switch组件用来渲染第一个匹配成功的组件

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

上面代码,但我的path为/about的时候,会同时渲染出Home组件跟About组件 是因为在模糊匹配下,/about这个路径也可以匹配到/,所以才造成上述问题,那么当我用了switch的时候,就只会渲染第一个匹配成功的。

< route path = "/" > 总是与 URL 匹配。正因为如此,我们通常将这个 < route > 放在 < switch > 中的最后

小tips:这里最好经常在path="/"Route内加exact属性,否则有可能会出现问题哦

Redrict组件

重定向组件,就是比如你输入/abc的时候给你切换到/下,一般跟render一起用

<Route path="/abc" render={() => {
     return <Redirect to="/" />;
     }}/>

上面的代码的意思是当path为/abc的时候,重新定向到/

Prompt组件

当用户离开当前页面前做出一些提示。

写在最后

由于React的文档写得实在阅读成本很高,如果抛开需求硬学API的话效率非常低,所以主张在项目中解决这些问题,目前对于基本使用,我们只需要知道上面得一些基础API即可,如果我后期发现更多好玩常用的的特性,也会随时更新在这篇博客上。