返回顶部
首页 > 资讯 > 前端开发 > JavaScript >浅谈React Router关于history的那些事
  • 346
分享到

浅谈React Router关于history的那些事

2024-04-02 19:04:59 346人浏览 薄情痞子
摘要

如果你想理解React Router,那么应该先理解history。更确切地说,是history这个为React Router提供核心功能的包。它能轻松地在客户端为项目添加基于loc

如果你想理解React Router,那么应该先理解history。更确切地说,是history这个为React Router提供核心功能的包。它能轻松地在客户端为项目添加基于location的导航,这种对于单页应用至关重要的功能。


npm install --save history

存在三类history,分别时browser,hash,与 memory。history包提供每种history的创建方法。


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

如果你使用React Router,他会为你自动创建history对象,所以你并不需要与history进行直接的交互。不过,理解不同类型的history依旧很重要,这样你能在项目中决定究竟是用哪个。

history是什么?

无论你创建哪种history,你最终都会得到一个几乎拥有相同属性与方法的对象。

location

history对象中最重要的属性就是location。location对象反映了当前应用所在的"位置"。其包含了pathname,search[注1],hash这种由'URL'派生出的属性。

此外,每一个location都拥有一个与之关联且独一无二的key。'key'用于特定location的识别,向特定location存储数据。

最后,location可以拥有与之相关的状态。这是一些固定的数据,并且不存在于URL之中。


{
 pathname: '/here',
 search: '?key=value',
 hash: '#extra-infORMation',
 state: { modal: true },
 key: 'abc123'
}

当创建一个history对象后,需要初始化location。对于不同类型history这一过程也不相同。例如,browser history会解析当前URL。

一个location控制所有?

诚然我们只能访问当前location,history对象持续追踪着一组location。正因为拥有添加location并能够访问数组中任意location的能力,history才能被称为“历史”。如果history只能记录当前location,那就应该叫它“present”。

除了一组location外,history也保存一个索引值,用来指向当前所对应的location。

对于memory history,它们被直接定义。而对于browser history与hash history,数组与索引被浏览器所控制,并不能直接访问[注2]。

navigation方法
可以说navigation方法是拥有location属性的history体系的点睛之笔。navigation允许你改变当前location。

push方法
push方法使能你跳转到新的location。通过在当前location后添加新的location时,任意的'未来'location会被清除(之前由后退按钮而形成的在当前location后的location)。

默认情况下,当你点击<Link>时,会调用history.push方法进行导航。


history.push({ pathname: '/new-place' })

replace
replace方法与push相似,但它并非添加location,而是替换当前索引上的位置。'未来'location将不会被清除。

重定向时要使用replace。这也是React Router的<Redirect>组件中使用的方法。

例如,当你在页面1通过点击link按钮导航到页面2,页面2可能会重定向到页面3。如果使用push方法,点击放回按钮将从页面3返回到页面2(这里有潜在的可能再重定向到页面3)。如果使用replace方法,会从页面三直接返回页面1。


history.replace({ pathname: '/Go-here-instead' })

go, go, go
最后有三个带‘go'的方法,它们分别是goBack,goForward与go。
goBack返回一层页面。实际上是将history的索引值减1。


history.goBack()

goForward与goBack相对。向前一层页面。这仅在拥有'未来'location生效,即当用户点击了后退按钮。


history.goForward()

go是一个强大的方法,并包含了goForward与goBack的功能。传入负数则退后,传入正数则向前。


history.go(-3)

监听!

采用观察者模式,在location改变时,history会发出通知。每一个history对象都有listen方法,接受一个函数作为参数。这个函数会被添加到history储存的监听函数数组中。当location变化时(如代码调用history方法或用户点击浏览器按钮),history对象将会调用所有listener方法。这能让你在location变化时来设置代码更新。


const youAreHere = document.getElementById('youAreHere')
history.listen(function(location) {
 youAreHere.textContent = location.pathname
})

React Router的router组件将会订阅history对象,这样当location变化时,其能重新渲染。

链接事物Linking things together

每一类history都拥有createHref方法,其使用location对象,输出URL。
内部,history通过location对象进行导航。然而像锚点元素(a),它并不知道history这个包,也不知道location对象是什么。为了能让生成的html 在不需要history的情况下,依旧能够导航。我们必须生成真的URL。


const location = {
 pathname: '/one-fish',
 search: '?two=fish',
 hash: '#red-fish-blue-fish'
}
const url = history.createHref(location)
const link = document.createElement('a')
a.href = url
// <a href='/one-fish?two=fish#red-fish-blue-fish'></a>

以上涵盖了基础的history api。虽然还有其他未介绍的属性与方法,但上述方法能够是你明白history对象是如何运作的。

结合在一起

不同类型的history间还是存在差异的,这需要你去考虑选择一个适合你项目的history。
Between the three of them, any use case should be covered.

在浏览器中

browser history与hash history都被用于浏览器环境。它们与history和location的WEB API进行交互,因此当前location与浏览器地址栏中展示的是相同的。


const browserHistory = createBrowserHistory()
const hashHistory = createHashHistory()

它们两者的最大区别在于从URL创建location的方式。browser history使用完整URL[注3],而hash history只使用在第一个hash后的那部分URL。


// 提供如下URL
url = 'Http://www.example.com/this/is/the/path?key=value#hash'
// browser history创建的location对象:
{
 pathname: '/this/is/the/path',
 search: '?key=value',
 hash: '#hash'
}
//hash history创建的location对象:
{
 pathname: 'hash',
 search: '',
 hash: ''
}

使用哈希

为何你需要hash history?理论上来说当你导航到一个URL时,服务端必有一个相应文件与之对应。对于动态服务,请求文件并不需要真实存在。相反,服务端会检查请求的URL并决定返回的HTML。

然而,静态文件服务可以直接返回存在磁盘中的文件。静态服务能做的最动态的事就是当URL制定目录时,从目录中返回index.html文件。

由于静态文件服务的这种限制,最简单的解决方案[注4]就是在服务端仅使用一个真实的location来返回用户端的获取需求。当然,仅有一个location意味着你的应用只有一个URL,这样就无法使用history。为了解决这一问题,hash history使用使用URL的哈希部分来读写location。


// 如果 example.com 使用静态资源服务, 这三个URL都将从
// /my-site/index.html获取相同数据
http://www.example.com/my-site#/one
http://www.example.com/my-site#/two
// 然而由于使用hash history,应用中三者的location是不同的,
// 因为location取决于URL的哈希部分
{ pathname: '/one' }
{ pathname: '/two' }

纵然hash history运作良好,但由于其依赖将所有路径信息存在URL的哈希中,它被认为有可能遭到黑客攻击。因此当网站没有动态服务时再考虑使用它吧。

memory:缓存所有history

使用memory location最棒的体验就是你可以在能使用javascript的地方随意使用。

一个简单的例子你可以通过运行node在单元测试中使用它。这允许你能在不依赖浏览器运行的情况下测试代码。

更牛逼的是,memory history可以被使用在app中。在react-nativeapp中react-router-native使用memory history来实现基于location的导航。

你可以在浏览器中使用使用memory history,如果你愿意的话。(虽然这样你会失去与地址栏的交互能力)。

这memory history与其他两类history最大的区别在于其维护着自己的location。当创建memory history后你可以传入信息进行初始化状态。这个状态是一个location数组与当前location的索引[注5]。这与其他两类history是不同的,它们依赖浏览器来存储这个location数组。


const history = createMemoryHistory({
 initialEntries: ['/', '/next', '/last'],
 initialIndex: 0
})

使用history代替你来处理哪些相对繁琐且易错的是一个行之有效的方法。

无论你选择了何种类型的history,他们都是极易使用,并且拥有强大的能力进行导航与基于loaction的渲染。

注释

[1] search属性是一个字符串而非被解析对象。由于大多数字符串解析包在使用上各不相同。所以history把选择权留给了开发者而不是强制使用某种字符串解析包。如果你想了解更多,这里推荐一些流行的:query-string,querystring与原生的URLSearchParams

[2] 这是出于安全性的限制。在浏览器中history的location数组不仅包涵了访问过的location信息。如果开放浏览会泄漏使用者的浏览器历史信息,因此无法开放访问。

[3] m默认情况下,browser history创建的location对象,它的路径名是URL全路径名。当然,你可以为history定一个基础名,这样路径名中的这部分将会被忽略。


const history = createBrowserHistory({ basename: '/path' })
// 给出的路径 url: http://www.example.com/path/here
// history对象将会创建如下location
{ pathname: '/here', ... }

[4] 理论上,可以让应用中的每个有效URL返回相同的HTML文件。虽然这可以事项,但如果所有的URL都是静态的,会产生大量冗余文件。不过任意地址都使用参数大量来匹配大量可能址是不可行的。
[5] 如果并未提供memory history的初始化location数组与索引,则会生成如下默认值:


entries = [{ pathname: '/' }]
index = 0

对于大部分应用这已经足够好了,但提前写入history对于恢复内容还是一个非常有用的方法。

到此这篇关于浅谈React Router关于history的那些事的文章就介绍到这了,更多相关React Router history内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 浅谈React Router关于history的那些事

本文链接: https://lsjlt.com/news/122922.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 浅谈React Router关于history的那些事
    如果你想理解React Router,那么应该先理解history。更确切地说,是history这个为React Router提供核心功能的包。它能轻松地在客户端为项目添加基于loc...
    99+
    2024-04-02
  • 浅谈关于axios和session的一些事
    发现问题 最近在工作中遇到一个问题,后端写好,前端写好,postman测试做好,一切都没有问题,但是实际用axios来实现登陆功能的时候问题就来了.... 什么情况?登陆根本用不了啊!每次都提示我没有登陆...
    99+
    2022-06-04
    浅谈 axios session
  • 浅谈C++/C关于#define的那些奇奇怪怪的用法
    目录前言1 缩减代码 2 定义变量3 代替函数 4 函数做不到的功能5 一些有些"邪门"的用法 6 与#define有关联的带&ld...
    99+
    2024-04-02
  • 关于 sudo 的那些事儿
    觉得你已经了解了 sudo 的所有知识了吗?再想想。大家都知道 sudo,对吗?默认情况下,该工具已安装在大多数 Linux 系统上,并且可用于大多数 BSD 和商业 Unix 变体。不过,在与数百名 ...
    99+
    2023-06-05
  • 关于 React 中 useEffect 使用问题浅谈
    目录前言优化前优化后总结前言 最近看了一下 ant-design 中的 tree 组件源码时发现 useEffect 中根据 props 来计算当前函数组件的 state 的,感到好...
    99+
    2024-04-02
  • 浅谈Python基础之列表那些事儿
    一、列表的格式 二、列表的相关操作("增"、"删"、"改",“查”) <1> 添加元素 append()通过append可以向列表添加元素。 例: 运行结果: <2> 修改元素("改")...
    99+
    2022-06-02
    Python列表操作 python list列表
  • 关于spring5的那些事:@Indexed 解密
    目录哪些资源会被索引?如何使用?原理随着云原生的发展,很多技术会被重新掂量,重新定义,历来技术的发展也是遵循天时地利,以其势尽享其利。再云原生下,jdk的最大的问题在于笨重(几百mb...
    99+
    2024-04-02
  • 浅谈 Python 网络爬虫的那些事(文末送书7.0)
    文章目录 📋前言🎯什么是网络爬虫🧩 网络爬虫概述 🎯爬虫案例🧩代码案例 🔥文末送书&#x...
    99+
    2023-09-20
    python 爬虫 开发语言 网络爬虫 Beautiful Soup 网络请求 原力计划
  • 关于索引我能说的那些事儿
    本文是自己对MySQL的InnoDB索引的理解,如有错误,还望不吝指出。 1 索引   索引两个大字往那里一摆,刚接触不久的朋友可能对这个概念有点陌生,不好理解。没有关系,先用一个简单的例子入手,比方说现在我们要从一本字典中查...
    99+
    2015-01-11
    关于索引我能说的那些事儿
  • 关于vue中api统一管理的那些事
    目录前情提要针对小项目而言(没有单独二次封装axios)无需管理,直接干。仅限于接口数量在20-30的统一api.js文件管理针对非小型项目而言(进行axios的二次封装)api统一...
    99+
    2024-04-02
  • 关于pt-archiver和自增主键的那些事
    目录前言分析解析结论本文Percona Blog 的译文,原文移步文章末尾的 阅读原文。 前言 pt-archiver 是一款常见的 表清理或者归档工具。 MySQL 中删除大表之前...
    99+
    2024-04-02
  • 关于区块链那些事(用Python3体现
    想知道更多关于区块链技术知识,请百度【链客区块链技术问答社区】 链客,有问必答! 未经允许,拒绝转载,https://www.liankexing.com/no... 要弄懂什么是区块链技术的前提,首先要知道什么是md5算法。给一个最...
    99+
    2023-01-31
    区块
  • 浅谈关于Android路由的实现
    先说一下背景,目前有需求从外部包括其他应用和WEB跳转到我们自己的APP,就这么个简单的需求……要实现这种外部跳转的功能,我们可以理解为打算跳转的一方有多少方式通知到APP进行相对的响应行为。所以,如果是应用之间的跳转,则有多种,你可以直接...
    99+
    2023-05-30
    android 路由 roi
  • 关于iOS自适应cell行高的那些事儿
    前言 其实早就准备写这篇文章了,但是一直没有系统去整理一下相关的demo,加上最近离职了,各种事情忙的有点郁闷,所以一直拖沓了下来。回家休息了一段时间想起来写了一半的demo,在还...
    99+
    2022-05-31
    cell 自适应 行高
  • 详解关于spring bean名称命名的那些事
    目录前言02源码查看01从main方法直接调试断点02带着问题查看,靠猜加验证的方式03源码验证04总结前言 用了多年spring,一直想当然把spring默认的beanName当成...
    99+
    2024-04-02
  • Java基础7:关于Java类和包的那些事
    更多内容请关注微信公众号【Java技术江湖】这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM、SpringBoot、MySQL、分布式、中间件、集群、Linux、网络、多线程,偶尔讲点Docker、EL...
    99+
    2023-06-02
  • 关于react-router中的Prompt组件使用心得
    目录Prompt组件作用引入Prompt组件在最近的react项目中, 遇到了一个需求, 点击图片的时候, 会出现一个大图预览, 其实就是一个遮罩层, 专门用来显示大图的, 但因为是...
    99+
    2023-01-17
    react router中Prompt组件 react router组件 Prompt组件
  • 关于C语言操作符的那些事(超级全)
    目录前言操作符的分类移位操作符位操作符赋值操作符单目操作符关系操作符逻辑操作符条件操作符逗号表达式下标引用符函数调用符结构体调用操作符总结前言 C语言中操作符不多,但是有些相同的操作...
    99+
    2024-04-02
  • 2020将至,谈谈中小企业创业的那些事儿
    2019正迎来尾声,在创业这场轰轰烈烈的旅途中,有的人名利双收,有的人饱受非议。一入创业深似海,在创业赛道上,很多公司完成了从0到1,却死在从1到100的路上。而小程序的出现,让移动互联网创业走向低门槛。正...
    99+
    2024-04-02
  • 关于@Controller和@Restcontroller的那点奇葩事
    目录@Controller和@Restcontroller直接甩正事后来的经验总结@Controller和@RestController的区别?@Controller和@Restco...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作