https://developer.mozilla.org/zh-CN/docs/Web/API/History/pushState
https://github.com/ReactTraining/history
https://github.com/ReactTraining/history#blocking-transitions

  • 这个库可以方便管理你的浏览记录。
  • 该包是 React Router 仅有的两大主要依赖之一(除去 React 本身),在不同的 Javascript 环境中,它提供多种不同的形式来实现对 session 历史的管理。

安装

  1. cnpm install history --save
  2. import createBrowserHistory from 'history/createBrowserHistory'
  3. import { createBrowserHistory } from 'history';

history 是可变的

history 对象是可变的,因此建议从的渲染选项中来访问location,而不是从history.location直接获取。这样做可以保证 React 在生命周期中的钩子函数正常执行。

  1. class Comp extends React.Component {
  2. componentWillReceiveProps(nextProps) {
  3. // locationChanged 将为 true
  4. const locationChanged = nextProps.location !== this.props.location
  5. // INCORRECT,因为 history 是可变的所以 locationChanged 将一直为 false
  6. const locationChanged = nextProps.history.location !== this.props.history.location
  7. }
  8. }
  9. <Route component={Comp} />

使用

  • “browser history” - 在特定 DOM 上的实现,使用于支持 HTML5 history API 的 web 浏览器中
  • “hash history” - 在特定 DOM 上的实现,使用于旧版本的 web 浏览器中
  • “memory history” - 在内存中的 history 实现,使用于测试或者非 DOM 环境中,例如 React Native

createBrowserHistory

使用 HTML5 历史 API 记录(pushState,replaceState和popstate事件)的使您的UI与URL保持同步。

  1. createBrowserHistory({
  2. basename: '/m', // 基链接
  3. //所有地址的基本网址。如果您的应用程序是从服务器上的子目录提供的,则需要将其设置为子目录。
  4. //格式正确的基本名应该有一个前导斜线,但是结尾不能有斜线。
  5. forceRefresh: false, // 是否强制刷新整个页面
  6. keyLength: 6, // location.key的长度
  7. // 用于确认导航的功能。默认使用 window.confirm。
  8. getUserConfirmation: (message,callback) => callback(window.confirm(message)) // 跳转拦截函数
  9. })

createHashHistory

使用 URL 的 hash 部分(即 window.location.hash )的使您的 UI 与 URL 保持同步。

注意:Hash 历史记录不支持location.key或location.state。在以前的版本中,我们试图填补行为,但存在我们无法解决的边缘案例。 任何需要此行为的代码或插件都将无法使用。由于此技术仅用于支持传统浏览器,因此我们鼓励您配置服务器以便与配合使用。

  1. createHashHistory({
  2. basename: '', // 所有位置的基本 URL,格式正确的基本名应该有一个前导斜线,但结尾不能有斜线。
  3. // 用于确认导航的功能。默认使用 window.confirm。
  4. getUserConfirmation: (message, callback) => callback(window.confirm(message)),
  5. hashType: 'slash', // 用于 window.location.hash 的编码类型。可用的值是:
  6. // "slash" - 创建像 #/ 和的 #/sunshine/lollipops hash 表 (默认)
  7. // "noslash" - 创建像 # 和的 #sunshine/lollipops hash 表
  8. // "hashbang" - 创建 “ajax crawlable” (由Google弃用)hash,如 #!/ 和 #!/sunshine/lollipops
  9. });

createMemoryHistory (手机端)

used as a reference implementation and may also be used in non-DOM environments, like React Native or tests

  1. createMemoryHistory({
  2. initialEntries: ['/'], // 初始载入路径,和MemoryRouter中的initialEntries是一样的
  3. initialIndex: 0, // initialEntries初始载入索引
  4. keyLength: 6, // location.key的长度
  5. getUserConfirmation: null // 路由跳转拦截函数
  6. })

示例

  1. const history = createHistory(); 创建历史对象
  2. const location = history.location; 获取location对象
  3. const unlisten = history.listen( (location, action) => {
  4. console.log(location,action)
  5. // location是location对象
  6. // action是动作名称,比如 "PUSH"
  7. } )
  8. history.push('/a', { some: 'state' }) // 强制跳转
  9. unlisten() // 监听解绑

history 对象

属性、方法总览

  • length - (number 类型) history 堆栈的条目数
  • action - (string 类型) 当前的操作(PUSH, REPLACE, POP)
  • location - (object 类型) 当前的位置。location 会具有以下属性:
    • pathname - (string 类型) URL 路径
    • search - (string 类型) URL 中的查询字符串
    • hash - (string 类型) URL 的哈希片段
    • state - (object 类型) 提供给例如使用push(path, state)操作将 location 放入堆栈时的特定 location 状态。只在浏览器和内存历史中可用。
  • push(path, [state]) - (function 类型) 在 history 堆栈添加一个新条目
  • replace(path, [state]) - (function 类型) 替换在 history 堆栈中的当前条目
  • go(n) - (function 类型) 将 history 堆栈中的指针调整n
  • goBack() - (function 类型) 等同于go(-1)
  • goForward() - (function 类型) 等同于go(1)
  • block(prompt) - (function 类型) 阻止跳转。(详见history 文档)。

createMemoryHistory中提供了额外的两个属性:
history.index 当前历史记录的索引
history.entries 历史记录

方法详解

listen

  • 监听历史对象中的路径变化,当路径发生变化后执行回调函数,参数就是最新的路径对象
  • history.listen 函数会返回一个 取消监听 的函数,我们可以在组件卸载的时候,调用它
    1. constructor(props){
    2. super(props);
    3. this.unlisten = history.listen( (location, action) => {
    4. console.log(location,action);
    5. })
    6. }
    7. componentWillUnmount(){
    8. this.unlisten && this.unlisten();
    9. }

push

使用push可以将一条新的历史记录推送到历史堆栈中

  1. history.push('/a');
  2. history.push('/a', {name: 'jack'});
  3. history.push({
  4. pathname: '/a',
  5. search: 'isShare=1&id=1',
  6. state: {
  7. name: 'jack'
  8. }
  9. });

replace

和push方法使用形式一样,replace的作用是取代当前历史记录

go

用来前进或者倒退,history.go(-1);

goBack

用来回退,history.goBack();

goForward

用来前进,history.goForward();

另外使用createMemoryHistory创建的history对象,有canGo方法,和go方法类似

使用history实现路由跳转警告

  1. const unblock = history.block('Do you want to leave?');

上面这个用法,就是添加一个跳转提示信息,默认使用dom环境的window.confirm,所以如果使用非dom环境的createMemoryHistory就要使用getUserConfirmation方法实现

另外,除了传递一个字符串提示信息以外,还可以添加函数

  1. const unblock = history.block( (location,action) => { return 'do you leave?' } )

可以通过直接调用,unblock(); 实现方法解绑

image.png