如何记录反应历史堆栈?

mou*_*777 7 reactjs

据我所知,React props 会保存您每次​​更新页面或导航到新页面时访问过的所有链接的历史记录。可以使用以下方式浏览此历史记录props.history.go(-number)

例如,如果我导航到

/home --> /home/startup --> /error
Run Code Online (Sandbox Code Playgroud)

我的历史记录将保存在某个地方["/home", "/home/startup", "/error"]

我触发

history.go(-2),我将被推送到 /home,并且历史堆栈将被重置到该点。

我问这个问题是因为我被迫保留一个自定义对象来跟踪所有用户导航,以便能够使用网站中的后退按钮将用户重定向到特定检查点。

例如:

const pushBack = () => {

    let historyArr: Array<string> = getNavigationHistoryArr();
    historyArr.reverse();

    //check the amount of spots between our tracked history last element and the checkpoints
    let spotsToRedirect: number = 0;
    for (let i in historyArr) {
      if (redirectCheckpoints.includes(historyArr[i])) {
        break;
      }
      spotsToRedirect--;
    }

    console.log("sportsToRedirect: "+spotsToRedirect)
    //whenever you have a long navigation stack
    if (spotsToRedirect < 0 && spotsToRedirect * -1 != historyArr.length) {
      removeSessionStorageEl(spotsToRedirect * -1)
      history.go(spotsToRedirect);
    }
    else {
      removeSessionStorageEl(historyArr.length)
      if(process.env.REACT_APP_TYPO3_URL){
        window.location.assign(process.env.REACT_APP_TYPO3_URL);
      }else{
        history.push("/")
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

重定向检查点是:

export const redirectCheckpoints : Array<string> = [
    /home 
]
Run Code Online (Sandbox Code Playgroud)

例如,将此代码指向大多数情况下应该可以正常工作。

如果我去/home --> /error --> /error ---> /error ---> /error(因为我正在重新加载错误页面)。上面的代码将产生一个history.go(-4)。这意味着重定向到 /home 删除其余的历史记录。但由于某种原因,它会随机失败,特别是如果我强制执行奇怪的行为,例如一直重新加载错误页面。

我通过在 app.tsx 文件中使用 didUpdate 和 didMount 来跟踪历史记录

    componentDidUpdate(prevProps) {
        
        if (this.props.location.pathname !== prevProps.location.pathname) {
          console.log("--didupdate1--")
          console.log("this.props.location.key: ",this.props.location.key)
        console.log("this.props.location.pathname: ",this.props.location.pathname)
          this.setDataLayer()
        }
    
        if (this.props.location.key !== prevProps.location.key || this.props.location.pathname !== prevProps.location.pathname) {
          trackNavHistory(this.props.location.pathname);
        }
      }

componentDidMount() {
   
    trackNavHistory(this.props.location.pathname);

  }
Run Code Online (Sandbox Code Playgroud)

那么...有没有办法实时读取历史堆栈并记录其数据?也许它会帮助我调试错误。

小智 2

React 本身没有路由,所以我在这里假设 React Router。

答案是:不,您无权访问历史堆栈。

它以这种方式工作,因为这就是History API 的工作方式工作方式。

为什么?因为当访问历史属性时,默认情况下,您正在使用下面的 window.history 。History API 不允许检查路径,因为这将是一个隐私缺陷,因为历史状态是关于选项卡中的整个浏览器历史记录,而不仅仅是您的域。

您可以尝试使用Router(而不是我猜您正在使用的 BrowserRouter )来接收历史记录,您可以在其中实现您自己的历史抽象:

import React from "react";
import ReactDOM from "react-dom";
import { Router } from "react-router";

const customHistory = {
  push(...) {
    ...
  }
}

ReactDOM.render(
  <Router history={customHistory}>
    <App />
  </Router>,
  node
);
Run Code Online (Sandbox Code Playgroud)

另一种选择是监听历史变化:

const unlisten = history.listen(({ location, action }) => {
  console.log(action, location.pathname, location.state);
});
Run Code Online (Sandbox Code Playgroud)

上面代码片段中的历史记录是传递给 Router 组件的历史记录对象。它可以在传递给组件之前通过this.props.history或通过useHistory进行访问钩子进行访问。

我认为这些实现无论如何都不能解决您的问题,因为它们只能在加载脚本后监听导航更改,因此在重新加载页面时它不会捕获添加到历史记录中的路径。