深入理解React Router:从原理到实践
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.2.2 history导航

1.history.push

history.push作为2.1节介绍过的历史对象的通用方法,类似于1.2节中的history.pushState,其主要作用为添加一个历史记录。其签名如下:

当第一个参数为字符串时,即真实导航路径,底层会使用history.pushState方法,无刷新改变URL;第二个参数对应为history.pushState的state对象,能持久化地存储状态在浏览器中。注意,state需要为可结构化克隆的对象,在1.2节中有过介绍。

若第一个参数为路径描述对象,则可将state、hash等值传入其中。

传入路径描述对象也等价于各部分字符串的拼接。

注意,对于browserHistory的每次push调用,都将产生一个随机的key值,该key值可从browserHistory.location中获取,并持久化存储于window.history.state中。这个随机值的字符串长度由创建history时的keyLength配置进行控制,默认为6,其作用为标识本次导航,将在2.5.2节介绍。

对于push方法,在history源码中的调用为pushState方法。

与原始的pushState方法不同的是,history.push方法的行为可在history.block被调用后改变,如:

与history.pushState不同的是,history.pushState函数不会触发popstate事件,history.pushState函数没有对应的回调监听;而没有被阻止的history.push方法会在状态更新后,触发history.listen监听的回调函数。回调函数的参数为当前最新的地址对象和值为“PUSH”的导航行为标识。

对于push,其都支持相对路径与仅带参数的调用方式,具体解析规则与1.2.3节中介绍的解析规则一致。

注意,当创建history的forceRefresh为true时,框架将不使用pushState原生方法,而是直接调用window.location.href=href刷新页面。

2.history.replace

与history.push一样,history.replace也可以改变浏览器地址。其声明为:

在调用history.replace时,产生的action为“REPLACE”。在使用上,history.replace的入参与history.push的入参类型均一致,既允许传入state对象,也可传入相对路径,同样可被history.block阻止。

与history.push不同的是,history.replace用于替换当前栈指针所指记录。在history源码内部,history.replace使用了history.replaceState:

在1.2.2节中曾介绍过history.replaceState,而history.push方法使用的是window.history.pushState,其会添加栈记录。对于history.replace,由于history.replaceState的调用不会触发popstate事件,所以history.replace的调用也不会触发popstate事件。

如果初始化的history的forceRefresh为true,则history.replace将使用window.location.replace(href)进行页面更新,强制刷新页面。

history.replace方法的key生成与history.push方法一致,调用history.replace后在location中将有一个随机key值,key值同样会持久化存储到window.history.state中。

key值将标识一次唯一的导航,可作为导航的唯一凭证。browserHistory在导航过程中产生的所有key值将被保存在内存中,用于标识栈记录,相关内容将在2.5.2节进行介绍。

3.history.go

history.go及history.goBack、history.goForward使用了window中的window.history.go方法,其仅做了简单的包装:

在1.3.1节中介绍过window.history.go等方法,其仅移动浏览器的栈记录指针,不对栈的内容产生影响,等同于浏览器的前进或后退操作。

当调用history.go等方法时,浏览器中监听的popstate事件回调函数会触发。browserHistory会监听此事件更新location地址,相关内容将在2.5.3节进行介绍。