侦听器未在React中卸载组件时被删除

时间:2018-06-12 15:10:19

标签: javascript reactjs react-router react-redux

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

我正在使用react-router-dom而我正在使用交换机组件。

我的路线:

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的帮助下访问检测网址更改的列表工具。我把它放在componentWillMount:

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

一旦用户更改了网址,这就会被火上浇油......但是。 让我们说我在&#34; /模拟&#34;这是我听任何网址更改的地方。当我搬到&#34; / room&#34; &#34; / simulation&#34;中的componentWillMount中的代码组件已执行,现在我正在使用新的URL ...

问题:如果我现在更改为&#34; / room&#34; to&#34; / intro&#34;然后是&#34; / simulation&#34;下的componentWillMount中的相同代码。会再次执行。

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

2 个答案:

答案 0 :(得分:2)

这是因为一旦组件卸载你没有清除历史监听器,你需要在组件卸载时清除监听器,你将在componentWillUnmount生命周期方法Simulation中执行< / p>

componentWillUnmount() {
    this.unlisten();
}

答案 1 :(得分:0)

上面的答案是正确的...但是我发现在

内取消注册存在问题
componentWillUnmount

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

所以我最终得到了以下内容:

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