【问题标题】:Listener not getting removed on component unmount in React在 React 中卸载组件时未删除侦听器
【发布时间】:2018-06-12 15:10:18
【问题描述】:

我已经在 react.js 中构建了一个 SPA,我正在使用 react-router-dom、react-redux 和其他一些模块。

我正在使用 react-router-dom 并且我正在使用 switch 组件。

我的路线:

const allRoutes = [
    {
      path: "/Intro",
      name: "Intro",
      component: Intro
    },
    {
      path: "/Room",
      name: "Room",
      component: Room
    },
    {
      path: "/Simulation",
      name: "Simulation",
      component: Simulation
    },
    {
      path: "/Cartypes",
      name: "Cartypes",
      component: CarTypes
    },
    {
      path: "/StartPosition",
      name: "StartPosition",
      component: StartPosition
    },
    {
      path: "/Movment",
      name: "Movment",
      component: Movment
    },
    { redirect: true, path: "/", to: "/Intro", name: "Intro" }
  ];

  export default allRoutes;

我如何渲染它们。

          <Switch>
              {routes.map((prop, key) => {
                if (prop.redirect)
                    return <Redirect from={prop.path} to={prop.to} key={key} />;
                return (
                  <Route path={prop.path} component={prop.component} key={key} />
                );

              })}
          </Switch>

场景

在我的一个组件中,我想检测用户何时离开该特定组件,何时更改 url。

为此,我发现我可以在withRouter 的帮助下访问检测 url 更改的侦听器。我把它放在componentWillMount中:

  componentWillMount() {
    this.unlisten = this.props.history.listen((location, action) => {
      console.log("on route change");
      console.log(location)
      console.log(action)
    });
  }

一旦用户更改了 url,就会触发这是所期望的……但是。 假设我在“/simulation”,这是我监听任何 url 变化的地方。当我移动到“/room”时,执行了“/simulation”组件中的componentWillMount中的代码,现在我在一个新的url上......

问题:如果我现在从“/room”更改为“/intro”,那么“/simulation”下的componentWillMount 中的相同代码将再次执行。

谁能告诉我为什么?以及如何阻止它执行多次?

【问题讨论】:

    标签: javascript reactjs react-router react-redux


    【解决方案1】:

    这会发生,因为一旦组件卸载您没有清除历史监听器,您需要在组件卸载时清除监听器,您将在 SimulationcomponentWillUnmount 生命周期方法中执行类似

    componentWillUnmount() {
        this.unlisten();
    }
    

    【讨论】:

    • 这太简单了,太合乎逻辑了,我不敢相信我没有想到。谢谢!
    【解决方案2】:

    上面的答案是正确的......但是我发现了一个在内部注销的问题

    componentWillUnmount
    

    问题是我在componentWillMount 中的代码从来没有机会执行,因为componentWillUnmount 首先/更快地执行。

    所以我最终得到了以下结果:

      componentWillMount() {
        this.unlisten = this.props.history.listen((location, action) => {
          // execute my code
          this.unlisten(); // unregister the listner. 
        });
      }
    

    【讨论】:

      猜你喜欢
      • 2016-11-28
      • 2017-03-03
      • 2022-07-27
      • 2022-08-03
      • 2015-10-10
      • 1970-01-01
      • 2018-09-04
      • 2020-09-04
      • 1970-01-01
      相关资源
      最近更新 更多