学习React Router

概念

“路由”是一个随处可见的东西,比如一座城里会有若干条道路通往若干个目的地,一个司机可以选择从哪条路到哪个地方。在单页面应用中会有若干个按钮或链接指向若干个组件或页面,有个叫路由器的东西就是用来设置路径和组件的对应关系的。

路由这个概念包含了三个部分:路径、目的地、路由器

React Router

React项目的路由库是 React Router,它分为三个部分:

  • react-router:核心组件
  • react-router-dom:浏览器路由库
  • react-router-native:native端路由库

核心库会随着两个端的库安装,所以在浏览器端只需要安装react-router-dom

组件

根据路由的概念,React Router也提供了三大类组件:

  • Link:让一个元素指向某个路径,比如:

  • Route:指定路径和组件的对应关系,比如:

  • Router:当链接被点击时,在若干个Route中寻找路径匹配的那一个,并渲染指定的组件

每类组件都针对不同的客户端提供了不同的组件,比如Router组件在浏览器端(其他端先不管)就提供了两种组件:

BrowserRouter 和 HashRouter

这两种组件分别是基于URL的pathname段和hash段的,很大的一个差别就是使用BrowserRouter时需要对服务器做一些设置,因为pathname会被发送到服务端。

一个简单应用

学习React Router_第1张图片

上图中黑框代表整个应用,由

组成。中设置了三个菜单项,点击后分别将对应的组件渲染到,而
则可以用来显示面包屑等组件。当前选中第三条菜单,渲染了 组件。这个组件内部又有两个链接,分别指向不同的组件。

在这个应用中,路由发生了嵌套:

  • App

    • /app1
    • /app2
    • /app3
      • /app3-1
      • /app3-2

路由配置

现在可以简单配置一下路由了,可以看到,不必把所有路由都放到一处。以下代码的,而各个组件的具体内容则简单放个标题也可以。

需要注意:

  • 必须用Router组件包裹整个应用,可以用HashRouter或者BrowserRouter
  • 可以在子组件内继续添加路由,但要记得把父组件所在的路由传递进去
//App.js
import React from "react";
import { HashRouter as Router, Route, Link, NavLink } from "react-router-dom";
import App1 from './App1'
import App2 from './App2'
import App3 from './App3'
import Header from './Header'
import Menu from './Menu'
import Content from './Content'

export default class MyApp extends React.Component{
render(){
   return(
       

有了这个应用骨架,剩下的问题就好办了,接下来还需要考虑这几个问题:

1. 路由匹配

当一个被点击时,其to属性的值就被拿去和Route的path属性匹配。

路由其实就是目录层级结构的表示,Route就相当于对文件系统的描述,一个Route就表示了哪个路径下有哪个组件。

路由匹配就是拿Link的to属性值去看看它能够被哪个目录所包含,比如:有三个Route,分别是//abc/abc/123,显然从前到后是包含关系。此时如果有一个路径为/abc/123/xyz的Link被点击,那么这三个Route都会匹配到。

那么问题来了,由于匹配到的Route都会被渲染,上面的结果就是点一个链接渲染了三个组件,而我们期望的是只渲染/abc/123/xyz,我只知道两个解决方法:

 /*-------------------- 方法1 -------------------*/
 /* exact:让上级Route只匹配路径完全一样的Link */
 

NavLink是特殊的Link,匹配到后,可以给它添加activeStyle或者activeClassName。

需要注意的是,匹配是Link和Route双方的事情,NavLink能够“感知”匹配从而改变自身样式,所以也要解决多个NavLink同时感知到匹配的问题,所以NavLink也需要使用exact,不然的话点击下级目录链接会导致所有上级目录Link变样式:

 

3. Route的三种渲染方式

  • component:给什么渲染什么

  • render:可以在渲染之前做点别的

   
  • children:可以根据是否匹配渲染不同组件,是否匹配可由自动传入的参数props.match获知
   

无论是否匹配到,children函数都会执行。不要在Switch中使用children!

4. 更多信息

一个路由被匹配到,其对应组件就会被传入三个props:match、location、history

URL参数

Link中可以给路由传参:

 

这个参数可以通过match.params.id拿到。

你可能感兴趣的:(学习React Router)