Как я могу зарегистрировать стек истории реакции?

#reactjs

#reactjs

Вопрос:

Насколько я знаю, react props хранит историю всех ссылок, которые вы посещали каждый раз, когда вы либо обновляете страницу, либо переходите на новую. Эту историю можно просматривать с помощью props.history.go(-number)

Например, если я перейду к

 /home --> /home/startup --> /error
 

Моя история будет сохранена где-нибудь как ["/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 amp;amp; 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("/")
      }
    }
  }
 

redirectCHeckpoints — это:

 export const redirectCheckpoints : Array<string> = [
    /home 
]
 

Укажите этот код, например, в большинстве случаев он должен работать нормально.

Если я перейду к /home --> /error --> /error ---> /error ---> /error (потому что я перезагружаю страницу с ошибкой). Приведенный выше код выдаст history.go(-4). Что означало бы перенаправление на / home, удаляющее остальную часть истории. Но по какой-то причине он случайно завершается сбоем, особенно если я постоянно применяю странное поведение, например, перезагружаю страницу с ошибкой.

Я отслеживаю историю, используя это didUpdate и didMount в моем файле app.tsx

     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);

  }
 

Итак … есть ли способ считывать стек истории в режиме реального времени и регистрировать его данные? Может быть, это поможет мне отладить ошибку.

Ответ №1:

Сам по себе React не имеет маршрутизации, поэтому я буду считать, что здесь используется React Router.

И ответ: нет, у вас нет никакого доступа к стеку истории.

Это работает таким образом, потому что именно так работает API истории.

Почему? Потому что при доступе к реквизиту истории по умолчанию вы используете window.history внизу. API истории не позволяет проверять пути, потому что это было бы нарушением конфиденциальности, поскольку состояние истории относится ко всей истории браузера на вкладке, а не только к вашему домену.

Вы можете попробовать использовать Router (вместо BrowserRouter, который, я полагаю, вы используете), который получает history prop, где вы можете реализовать свою собственную абстракцию истории:

 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
);
 

Другой вариант — прослушивание изменений истории:

 const unlisten = history.listen(({ location, action }) => {
  console.log(action, location.pathname, location.state);
});
 

история в приведенном выше фрагменте — это объект истории, переданный компоненту маршрутизатора. К нему можно получить доступ перед передачей компоненту через this.props.history или через хук useHistory .

Я не думаю, что какая-либо из этих реализаций в любом случае решит вашу проблему, потому что они могут прослушивать изменения навигации только после загрузки скриптов, поэтому он не будет улавливать пути, добавленные в историю при перезагрузке страницы.