说说react-router里的history

480 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天,点击查看活动详情

前言

react-router-dom中,router会给其子组件注入路由信息,通过在子组件的props读取,我们可以得到相应的路由信息。

通过下面的代码为例:

import React from "react";
import { Route, BrowserRouter as Router, Switch, Link } from "react-router-dom"
import Index from "./components/Index";
import Home from "./components/Home"

export default function App() {
  return <>
    <Router>
    <Link to="/index" >index</Link>
    <Link to="/home" >home</Link>
      <Switch>
        <Route children={Index} path="/index" exact />
        <Route children={Home} path="/home" exact />
      </Switch>
    </Router>
  </>
}
export default function Index(props) {
    console.log(props)
    return (
        <h1>Index</h1>
    )
}
const Home = (props) => {
    console.log(props)
    return <>
        <h1>Home</h1>
    </>
}
export default Home

在/index页面下观察控制台输出: image.png

在/home页面下观察控制台输出:

image.png

其中match方法中的参数,我们在之前的篇章中介绍过,其内部实现主要依靠path-to-regexp这个库去实现。

而路由对象里的history则主要依靠history这个库去实现。

路由信息里的history对象

路由信息里的history对象提供了一些方法,用于控制和监听地址的变化。

需要注意的是,该对象并不是window.history,而是一个抽离的对象,它提供统一的API接口,封装了具体的实现,具体如下:

  • createBrowserHistory 产生的控制浏览器真实地址的history对象
  • createHashHistory 产生的控制浏览器hash的history对象
  • createMemoryHistory 产生的控制内存中地址数组的history对象

history对象共同的特点:通过维护了一个地址栈去实现逻辑上的前进后退(pop)与新增地址(push)。

history对象里的信息:

  • action:当前地址栈,最后一次操作的类型
    • 如果是通过createXXXHistory函数新创建的history对象,action固定为POP
    • 如果调用了history的push方法,action变为PUSH
    • 如果调用了history的replace方法,action变为REPLACE
  • push:向当前地址栈指针位置,入栈一个地址。
  • replace:替换指针指向的地址。
  • go:控制当前地址栈指针偏移,如果是0,地址不变;如果是负数,则后退指定的步数;如果是正数,则前进指定的步数;
  • length:当前栈中的地址数量
  • goBack:相当于go(-1)
  • goForward:相当于go(1)
  • location:表达当前地址中的信息
  • listen:函数,用于监听地址栈指针的变化,该函数接收一个函数作为参数,该参数表示地址变化后要做的事情。
    • 参数1(location):记录了新的地址
    • 参数2(action):进入新地址的方式
      • POP:指针移动,调用go、goBack、goForward、用户点击浏览器后退按钮
      • PUSH:调用history.push
      • REPLACE:调用history.replace
    • 该函数有一个返回值,返回的是一个函数,用于取消监听
  • block:用于设置一个阻塞,当页面发生跳转时,会将指定的消息传递到getUserConfirmation,并调用getUserConfirmation函数
    • 该函数接收一个字符串作为参数,表示消息内容,也可以接收一个函数作为参数,函数的返回值是消息内容
    • 该函数返回一个取消函数,调用取消函数可以解除阻塞
  • createHref:basename + url

image.png

history库

安装:

yarn add history

使用:

import {createBrowserHistory,createHashHistory,createMemoryHistory} from "history"

createBrowserHistory

创建一个使用浏览器History Api的history对象

其配置对象如下:

  • basename:设置根路径
  • forceRefresh:地址改变时是否强制刷新页面
  • keyLength:location对象使用的key值长度
    • 地址栈中记录的并非字符串,而是一个location对象
  • getUserConfirmation:一个函数,该函数当调用history对象block函数后,发生页面跳转时运行

createHashHistory

createHashHistory创建一个使用浏览器hash的history对象 其配置对象如下:

  • hashType:#号后给定的路径格式
    • hashbang:被chrome弃用,#!路径
    • noslash:#a/b/c
    • slash:#/a/b/c

createMemoryHistory

创建一个使用内存中的地址栈的history对象,一般用于没有地址栏的环境。

小结

react-router的history对象主要依赖history这个第三方库。

createBrowserHistory、createHashHistory、createMemoryHistory,虽然名称和参数不同,但是返回的对象结构(history对象)完全一致。