【问题标题】:React Router v4 replace history when component is unmounted卸载组件时 React Router v4 替换历史记录
【发布时间】:2020-02-04 08:48:54
【问题描述】:

我有一个包含以下组件的应用程序

|__Base - /home/Base

|__Try - /home/Base/:try

|__Report - /home/Base/:try/report

Base 是起始屏幕,用户点击一个按钮并点击 Try,在尝试了一些事情后,他点击了提交,这会生成具有一些后端交互的报告,当获取数据时,它会加载报告。

所以我想要的是当用户从报告页面点击返回按钮时,他不应该登陆 Try 页面,而是登陆 Base 页面。

为此,我浏览了反应路由器文档,并尝试在 componentWillUnmount 上使用 history.replace 报告页面

this.props.history.replace(`/home/Base`, {
  pathname: `/home/Base`,
  search: null,
  state: {
    isActive: true
  }
}, null);

如果报告页面已完全加载并且我按下后退按钮它可以工作,但也会调用 Try Render 方法,然后将我带到基本页面,但如果报告未完全加载并且我按下后退按钮而正在加载微调器,它仍然会进入基本页面,但也会安装和卸载 TRY 组件。

我在这里缺少什么,是什么导致它挂载/卸载或渲染前一个组件,然后加载基础组件,即使我替换了历史堆栈?

【问题讨论】:

  • 毫无疑问,但是使用链接按钮直接路由到上一页呢?
  • @keikai 如果用户按下浏览器后退按钮会怎样
  • 感谢您的解释,仍然没有问题,但是,也许我们可以在Try中设置componentWillMount来检查上一页是否为Report,如果是,则路由到Base,是这是一个好方法吗?
  • 我没有得到解决方案,你能不能详细说明

标签: reactjs react-router react-router-v4


【解决方案1】:

原因

与此issue相关

React v16,改变路由,新路由的componentWillMount在旧路由的componentWillUnmount之前调用

更新:

解决方案(已检查,稍后更新在线演示)

使用react-router-last-location 获取以前的路径名

import { BrowserRouter, Switch, Route, Redirect } from 'react-router-dom';
import { LastLocationProvider } from 'react-router-last-location';

<BrowserRouter>
  <LastLocationProvider>
    <Switch>
     ...
    </Switch>
  </LastLocationProvider>
</BrowserRouter>

检查componentWillMount中的前一个路径名,如果是来自某个页面,则推送一个新的路径名进行路由。

  componentWillMount() {
    const { history, lastLocation } = this.props;
    if (lastLocation?.pathname === '/home/Base/:try/report') {
      history.push({pathname: '/home/Base'});
    }
  }

您可以使用他们提供的 HOC 或自己编写参考 lib 的源代码以减少依赖关系

import { withLastLocation } from 'react-router-last-location';

interface Props {
  lastLocation: any,
  history: any,
}

export const YourComponent = withLastLocation(connect(
  ...
))

通过这种方式,无论您点击back 按钮还是点击浏览器中的后退,您都可以从特定页面重定向所有路由过程,而无需挂载当前页面。

【讨论】:

  • 你将如何获得if (lastLocation.pathname 可以请你在那里阐明一下
  • 我上面也提到了,还有react-router-last-location这样的库,请随意查看。
  • 我确实同意解决方案,但为了获得最后一个解决方案,我需要导入 51.kb 的库,我认为这是一个解决方案.. 这有效,但不适用于准备好的产品代码,如果我没有任何实用程序怎么办?我们如何解决这个问题。这种看起来像是一种解决方法,而不是使用反应路由器的潜在解决方案
  • 你说的是对的,而且你仍然可以观看像here 这样的库的来源,然后在你自己的项目中自己做,这就是我真正的意思,我的意思是这个库提供了你可以参考的解决方案。
  • 上面的答案似乎已经很好地回答了你的问题。如果您需要任何进一步的帮助,请鼓励我。
猜你喜欢
  • 1970-01-01
  • 2017-07-29
  • 1970-01-01
  • 2017-12-08
  • 2017-07-30
  • 2015-11-14
相关资源
最近更新 更多