TL;DR
React Router中很重要的一部分就是history package
,他给react router提供了主要的功能。
npm install --save history
history is a JavaScript library that lets you easily manage session history anywhere JavaScript runs. history abstracts away the differences in various environments and provides a minimal API that lets you manage the history stack, navigate, confirm navigation, and persist state between sessions.
History Package中使用的history object是基于HTML5 history API。也就是对window.history
这个object的封装。
History能够确保SPA Project在client-side
方便的添加基于位置的导航。一个 history 知道如何去监听浏览器地址栏的变化, 并解析这个 URL 转化为 location 对象, 然后 router 使用它匹配到路由,最后正确地渲染对应的组件。
在React Router中一共有三种类型的history,分别是BrowserHistory
HashHistory
MemoryHistory
,React Router会自动的帮你创建这些history。
What Is History?
History可以是一个Object,不论是哪一种类型的history,产生的history object包含的属性都是一样的。Object 中要分成两部分:
- Location properties
- Navigation Method
History记录了整个访问历史中所有的location,维护了一个location的数组,并且还有一个index指向数组中当前的location。但是为了安全性你无法获取到这个location的数组,只能访问到当前的location。
对于browser and hash histories
这个location数组和index都被浏览器控制和维护,你无法直接获取。但是memory history(for mobile)
这些locations以及index需要被显示的定义。
Location
Location是一个Object,描述的是当你的spa停留的位置。Location Object是一个形如:
{
pathname: '/here',
search: '?key=value',
hash: '#extra-information',
state: { modal: true },
key: 'abc123'
}
image.png
-
pathname
search
hash
这三个都是根据上图从URL中获取到的,注意为了安全性,history5 api只能获取到当前页面所在的location信息。 -
key:每一个Location都会有一个独一无二的key,唯一的代表一个Location,也用于存储数据到某一个对应的location。
-
state:想要传递数据给一个Location除了使用query将数据放在URL中带过来,也可以使用state,这个state相当于是放在这个location上的数据,这些数据不会出现在URL中。
Navigation Method
Navigation Method允许你改变当前的location。
-
push
:这个方法允许你jump到一个新的location。这时候会push一个新的location到history数组。history.push({ pathname: '/new-place' });
参数可以是location object也可以是一个url。但是只有前者可以传数据。当你click on a <Link> 将会使用
history.push
做navigation。
除此之外还有Replace({ pathname: '/go-here-instead' });
,goBack(), goForward(), go(-3)
等Navigation的方式。
Listen
History使用观察模式,会在监听地址栏的变化,在location发生改变的时候向外部代码发送notification
.
history.listen方法接受一个函数作为参数,这个函数将会被加在一个listener functiones的array中,然后被存储在这个history中。因此只要location发生改变就会一次调用数组中的函数。
Note: 一个React Router Component(Router/Route)会订阅自己的history,保证只要location发生改变,组件就可以重新render
createHref
这是一个用来将Location object转换成URL的function.
除了React Router中history的Navigation方法或者<Link>
标签可以使用Location object
作为参数,其他的纯HTML tag 比如a
就只能接受一个URL作为href的value,因此我们可以使用createHref
将location转换成URL string
三种不同history的区别
在浏览器上使用
Hash History
& Browser History
都是在浏览器上使用的,这两种history的区别在于创建location
的方式不同。前者使用URL中第一个#
之后的部分做location, 后者使用URL中整个URL做Location。
本质区别在于使用的server处理URL请求的方式不同。
-
Hash History的server只需要serve一个请求,能保证这个请求能够返回同一个文件即可
http://www.example.com/my-site#/one http://www.example.com/my-site#/two // 以上请求发到server之后,server必须能够保证请求`http://www.example.com/my-site`发过去能够返回一个文件。对于server端不需要创建多个路由,只要my-site一个即可 // the hash section of the URL { pathname: '/one' } { pathname: '/two' }
因为事实上,不同的路由对于服务器而言都是同一个请求。
-
browser History的server需要创建多个URL的controller,保证能够serve所有route
Memory: The Catch-all History
这种类型的history可以被用在任何可以运行js的环境中
这种类型的history通常被用来做单元测试(没有浏览器环境),以及Mobile。
这种类型的history和以上两种最大的区别就是这种类型是自己维护一个location array的。
网友评论