React专题6: 路由React Router

1. 后端路由与前端路由

多页面应用和后端路由
在传统的Web应用中,浏览器根据地址栏的URL向服务器发送一个HTTP请求,服务器根据URL返回一个HTML页面。这种情况下,一个URL对应一个HTML页面,一个Web应用包含很多HTML页面,这样的应用就是 多页面应用;在多页面应用中,页面路由的控制由服务器端负责,这种路由方式称为 后端路由

单页面应用和前端路由
URL的变化可以引起页面内容的变化,但不会向服务器发送新的请求,页面的内容也会发生变化,但这只是逻辑上的页面变化,无论URL如何变化,对应的HTML文件都是同一个,这样叫做 单页面应用. 在单页面应用中,URL发生变化并不会向服务器发送新的请求,所以“逻辑页面”(这个名称用来和真实的HTML页面区分)的路由只能由前端负责,这种路由方式称为 前端路由

React Router就是一种前端路由的实现方式。通过使用React Router可以让Web应用根据不同的URL渲染不同的组件,这样的组件渲染方式可以解决更加复杂的业务场景。例如,当URL的pathname为/list时,页面会渲染一个列表组件,当点击列表中的一项时,pathname更改为/item/:id(id为参数),旧的列表组件会被卸载,取而代之的是一个新的单一项的详情组件。

2. 安装路由

npm install react-router-dom

React Router包含3个库:react-router、react-router-dom和react-router-native。
react-router提供最基本的路由功能,实际使用时,我们不会直接安装react-router.
而是根据应用运行的环境选择安装react-router-dom(在浏览器中使用)或react-router-native(在react-native中使用)。
react-router-dom和react-router-native都依赖于react-router,所以在安装时,react-router也会自动安装。
所以我们只需要安装 react-router-dom

3. 引入路由

引入路由

// 哈希模式
import {HashRouter as Router, Link, Route} from 'react-router-dom'

//或者

// history模式
import {BrowserRouter as Router, Link, Route} from 'react-router-dom'

// ReactRouter三大组件
// Router 所有路由组件的根组件, 包裹路由规则的最外层容器
// Route 路由规则匹配组件, 显示当前规则对应的组件
// Link  路由跳转组件

4. HashRouter和BrowserRouter

Router可以理解成路由器,一个应用中只需要一个Router实例, React Router中的其他组件必须作为Router组件的后代组件使用。但Router中只能有唯一的一个子元素
Router会创建一个history对象,history用来跟踪URL,当URL发生变化时,Router的后代组件会重新渲染。React Router中提供的其他组件可以通过context获取history对象

BrowserRouter使用HTML 5的history API(pushState、replaceState等)实现应用的UI和URL的同步
BrowserRouter创建的URL形式如下:http://example.com/some/path
使用BrowserRouter时,一般还需要对服务器进行配置,让服务器能正确地处理所有可能的URL。例如,当浏览器发送http://example.com/some/pathhttp://example.com/some/path2两个请求时,服务器需要能返回正确的HTML页面(也就是单页面应用中唯一的HTML页面)

HashRouter使用URL的hash实现应用的UI和URL的同步。
HashRouter创建的URL形式如下:http://example.com/#/some/path
使用HashRouter则不存在这个问题,因为hash部分的内容会被服务器自动忽略,真正有效的信息是hash前面的部分,而对于单页面应用来说,这部分内容是固定的

5. Route

Route是匹配组件, 常用的属性有path和component.

Route的exact和strict修饰符

exact 精确匹配 默认为false,如果为true时,需要和路由相同时才能匹配。
false 路由:'/Home' url '/Home' 和 '/Home/myPage' 都会匹配
true 路由:'/Home' 只有url '/Home'才匹配, url '/Home/myPage' 不匹配

strict 斜杠敏感 默认为false,如果为true时,url对斜杠敏感
false url '/Home' 和 url '/Home/' 视为相同的url
true url '/Home' 和 url '/Home/' 视为不相同的url

6. Link

Link是跳转组件, 常用的属性是 to
to属性值可是字符串
也可以是对象: 这个对象包含 pathname、search、hash、state四个属性
例如:

let toArgs = {
    // 跳转的路径
    pathname: '/User',
    // get的入参
    search: '?user=admin',
    // hash的值
    hash: '#abc',
    // 组件的值
    state: {fromHome: true}
}

组件中的 this.props.location 存放着这个入参
在组件中查看这个入参:
this.props.location.state.fromHome;

7. switch

当 Router中的Route有多个符合匹配条件时, 如果不添加switch, 所有匹配的组件都会渲染
当 这些Route被 switch包裹时, 当第一个符合匹配条件的组件渲染后, 不再向下匹配. (保证只显示第一个匹配的组件)

8. history

路由页面跳转
history.push(path,[state])
history.replace(path,[state])
区别:
push是把新页面放入栈中, 保留上一个页面的历史记录, 这样返回还可以回到上一个页面
replace是把新页面替换上一个页面在栈中的历史记录, 这样返回的时候会回到上上个页面
现在有三个页面 a->b->c
b跳转c的时候, 如果使用push到c页面,在c页面点击返回回到b页面
b跳转c的时候, 如果使用replace到c页面,在c页面点击返回回到a页面

// 向前或向后跳转n个页面, 正数为前进, 负数为后退
this.props.history.go(n)

// 前进
this.props.history.go(1);
//或者
this.props.history.goForward();

// 回退
 this.props.history.go(-1);
//或者
this.props.history.goBack();

9. 动态路由

Route这样写 /path/:动态参数 如:

Link这样写 /path/具体的参数 如:
用户
生产的url是 #/User/admin
组件的this.props.match.params 存放这个动态参数
在组件中查看这个动态参数
this.props.match.params.user;

10. Redirect重定向

待补充...

11. 组件被加入路由后, 组件的this.props新增属性

this.props.history

this.props.history提供了push, replace, go, goBack, goForward等方法

// this.props.history.go(n)
// 向前或向后跳转n个页面, 正数为前进, 负数为后退

// 前进
this.props.history.go(1);
this.props.history.goForward();

// 回退
this.props.history.go(-1);
this.props.history.goBack();

this.props.location

this.props.location存放的是Link to属性传入的对象,包括pathname、search、hash、state四个属性

let toArgs = {
    // 跳转的路径
    pathname: '/User',
    // get的入参
    search: '?user=admin',
    // hash的值
    hash: '#abc',
    // 组件的值
    state: {fromHome: true}
}
登录
// 组件中的 this.props.location 存放着这个入参
// 在组件中查看这个入参
this.props.location.state.fromHome;

this.props.match

this.props.match.params存放着动态路由的动态参数

// Route这样写 /path/:动态参数 如:

// Link这样写 /path/具体的参数 如:
用户
// 访问这个属性: 
this.props.match.params.user;

11. window.location

页面刷新时, 如果想要访问到当前页面的哈希路径, 以此来作为判断条件做一些预处理, 在react的生命周期函数UNSAFE_componentWillMount执行时, props属性还没有被注入数据的情况, 可以通过window.location来访问到hash路径

UNSAFE_componentWillMount(){
    /* 每次刷新页面时,可以通过window.location获取到当前的hash路径, 以此来获取一下当前页等信息. 
    然后定位对应的位置等操作. 因为页面刚刷新, 在willMount的时候我们还无法访问props.
    */
    console.log('页面刷新时会调用这个方法. 来查看一下刷新时的hash路由');
    //可以看到这时候props还没有数据, 如果想拿到哈希路径, 就需要访问window.location
    console.log('this.props',this.props); 
    console.log(window.location.hash);
    console.log(window.location.hash.split('/'));
    console.log(window.location.hash.split('/')[1]);
  }

你可能感兴趣的:(React专题6: 路由React Router)