【问题标题】:In React.js, using componentWillUnmount to remove an event listener, how can I make sure the event listener gets removed?在 React.js 中,使用 componentWillUnmount 删除事件监听器,我如何确保删除事件监听器?
【发布时间】:2017-01-16 20:41:12
【问题描述】:

卸载组件后,调整窗口大小时出现错误。我知道window.removeEventListener 正在被调用,但它的行为就好像它永远不会被调用一样。错误说:

warning.js:36 警告:setState(...): Can only update amounted or 安装组件。这通常意味着您在一个 未安装的组件。这是一个无操作。请检查代码 HeaderMain 组件。

我什至尝试使用 React 文档中的代码示例,它与我的班级正在做的事情相同。来自https://facebook.github.io/react/tips/dom-event-listeners.html

import React from "react";

var HeaderMain = React.createClass({
  getInitialState: function() {
    return {windowWidth: window.innerWidth};
  },

  handleResize: function(e) {
    this.setState({windowWidth: window.innerWidth});
  },

  componentDidMount: function() {
    window.addEventListener('resize', this.handleResize);
  },

  componentWillUnmount: function() {
    window.removeEventListener('resize', this.handleResize);
  },

  render: function() {
    return <div>Current window width: {this.state.windowWidth}</div>;
  }
});

module.exports = HeaderMain;

我尝试过使用bind(),我已经尝试过ES6,并尝试过不同版本的React.js。我无法摆脱错误。

如何确保我的事件监听器会被移除?

【问题讨论】:

  • 这段代码应该可以正常运行。您可能实际上并未粘贴说明问题的代码。
  • 不,我确实做到了。此代码不起作用,除了最后一行之外,它与 React 文档中的示例几乎相同。请参阅下面的解决方案。

标签: javascript reactjs


【解决方案1】:

我发现它与绑定有关。当您调用 .bind(this) 时,它会返回一个具有所需范围的新函数,因此它并没有取消注册我以为我添加的同一个函数。

此外,无论出于何种原因,我发现在 ES6 + React v15.3.1(最新)中,自动绑定不会发生(我认为它应该发生),因为它在 ES5(相同版本的 React)中发生,所以我只是存储了对绑定函数的引用,然后重用它。

import React from "react";

export default class HeaderMain extends React.Component {

  boundFunc = this.handleResize.bind(this);

  constructor()
  {
    super();

    this.state = {height:window.innerHeight + "px"};
  }

  handleResize(e)
  {
    this.setState({height:window.innerHeight + "px"});
  }

  componentDidMount()
  {
     window.addEventListener('resize', this.boundFunc);
  }

  componentWillUnmount()
  {
    window.removeEventListener('resize', this.boundFunc);
  }

  render() {

    return (
      <header class="header_main" style={{height:this.state.height}}>
         Example Header
      </header>
    );
  }
}

【讨论】:

【解决方案2】:

不用担心这个警告,你可以像这样在handleresize 函数中使用console.log() 进行测试:

 handleResize: function(e) {
    this.setState({windowWidth: window.innerWidth} , function(){
    console.log("windowWidth" , windowWidth);
    });
  }

通过更改路线或任何操作来测试它以调用componentWillUnmount 函数,然后打开您的console 并调整窗口大小。

【讨论】:

    猜你喜欢
    • 2015-02-27
    • 2011-05-23
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多