React Router v4 - 如何检测后退按钮导航与 url 刷新?

Posted

技术标签:

【中文标题】React Router v4 - 如何检测后退按钮导航与 url 刷新?【英文标题】:React Router v4 - How to detect back button navigation vs url refresh? 【发布时间】:2018-02-10 00:54:22 【问题描述】:

我在/page (PAGE A) 有一个网址,我想检测该页面是否从 (PAGE B) 导航到历史记录,或者是否用户在 (PAGE A) 上并通过 URL 栏刷新按钮手动刷新页面(不使用历史返回)。

我通过 react router 查看了所有历史记录、位置、道具,但没有找到区分用户如何导航到页面的方法。

在这两种情况下,history.action == 'POP' 是历史操作。理想情况下,当使用应用程序中的后退按钮从页面 b 回到页面 a 时,它会是 'POP',而在页面 a 上,当刷新页面时,它将是 'POP' 以外的东西,例如 'REFRESH'例子。

我们如何区分它们以在我们的应用程序中运行不同的逻辑,因为它们都触发了'POP'

【问题讨论】:

使用历史,添加监听并监听pop,npmjs.com/package/history 我认为您正在寻找我在这里回答的这种东西:***.com/questions/41862910/… 【参考方案1】:

可以不比较历史键,而是比较路径名,例如,如果您在页面“/page1/page2”并点击刷新,则新位置是相同的。但是如果你点击返回操作,新的位置将是“/page1/”。

此解决方案还使用侦听器来侦听来自历史记录的任何操作。

  componentDidMount() 
    const unlisten = history.listen((location, action) => 
        if (action == 'POP') 
          \\ thisLocation is the current location of your page
          if (location.pathname != '/thisLocation/') 
            alert('Back Pressed: ' + String(location.pathname));
           else 
            alert('Refreshed: ' + String(location.pathname));
          
        
    );
    this.setState( ...this.state, unlisten: unlisten );
  

  componentWillUnmount() 
    this.state.unlisten();
  

您可以在 Rei Dien 提供的链接中查看更多详细信息,作为您问题的评论:https://www.npmjs.com/package/history

[编辑]

另一种方法是使用https://www.npmjs.com/package/react-router-last-location 并这样做:

import  useLastLocation  from 'react-router-last-location';

  componentDidMount() 
    const unlisten = history.listen((location, action) => 
          const lastLocation = useLastLocation();
          if (location.pathname == lastLocation.pathname) 
            alert('Back Pressed: ' + String(location.pathname));
          
        
    );
    this.setState( ...this.state, unlisten: unlisten );
  

  componentWillUnmount() 
    this.state.unlisten();
  

不利的一面是,激活后退操作或单击指向您之前所在页面的链接之间没有区别,两者都会被检测为按下后退。如果您不想要新的依赖项,您可以按照https://github.com/ReactTraining/react-router/issues/1066#issuecomment-412907443 创建中间件中的说明手动进行。

【讨论】:

嘿,不幸的是,这也不起作用。即使返回会触发 Refreshed 并且页面刷新不会触发任何警报。我很惊讶反应路由器库中没有内置解决方案! 这很好奇。它在这里工作得很好。尝试在 if (action == 'POP') 的 else 上发出警报,并将操作作为参数。如果您总是收到 PUSH 操作,我将使用另一种解决方案更新答案。如果是这种情况,您将需要制作一个中间件,以便能够存储最后一个位置并与下一个位置进行比较。 您好,感谢您为回答所做的努力。我授予你赏金,因为它即将到期,我希望你拥有它而不是丢失它。我仍然没有找到解决它的方法,但发布在 github 上的 react/history repo 上。如果我得到一些工作,我会在这里发布作为答案。再次感谢! 谢谢,我仍然愿意为您的问题找到解决方案。似乎没有内置的方法来区分这些操作github.com/ReactTraining/history/issues/575。我现在能看到的最好的情况就是我说的将刷新视为“没有位置更改”,将返回操作视为“位置已更改”。【参考方案2】:

我认为这至少会为您指明正确的方向。导航到 yourwebsite.com。

let current_page = history.state.key

if(history.action == 'POP') 
  if(history.state.key == current_page) 
    return 'page was refreshed'
  
  return 'back button was pressed'

【讨论】:

嘿,所以我试过了,但没有状态键,只有位置键。我更改了history.location.key 而不是history.state.key,但无论页面刷新还是返回页面,都会返回“页面已刷新”。键是完全相同的,所以我们仍然无法区分刷新和返回页面。

以上是关于React Router v4 - 如何检测后退按钮导航与 url 刷新?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 react-router v4 检测路由变化?

如何知道react-router是不是可以返回以在react app中显示后退按钮

React Router v4动画转换示例

react-router v4 按需加载的配置方法

使用 React Router v4.1 的分页问题

React-router v4教程