【问题标题】:Why does removeEventListener not work on event handlers installed by React?为什么 removeEventListener 不适用于 React 安装的事件处理程序?
【发布时间】:2016-04-07 21:40:09
【问题描述】:

我有一个 React 组件,它会将一堆 li 元素附加到 DOM。他们中的一些人点击了Eventlistener。在用户单击那些特殊的li 后,我试图禁用事件监听器,我为此使用event.currentTarget.removeEventListener('click', this.handleMouse),但它不起作用。以下是代码的相关部分:

var DisplayList = React.createClass({
  /* ... */
  
  handleMouse: function (event) {
    event.currentTarget.style.backgroundColor = 'white';
    this.props.changeCounts(-1); 
    event.currentTarget.removeEventListener('click', this.handleMouse); //NOT WORKING
  },

  /* ... */

  render: function () {
    var self = this;
    return(
      <div id = "listing-boxes-wrapper">
          {
            this.props.sortedList.map(function(item, index){
              if (self.state.changedHabit.indexOf(item.habitid) > -1) {
                return  <li key={index} style={{backgroundColor: '#ccc'}} className = "text-center" onClick={self.handleMouse}>{item.description} 
                        </li>
              }else{
                return  <li key={index} className =" text-center">{item.description}
                        </li>
              }
            })
          }
      </div>
    )
  }
});

【问题讨论】:

    标签: javascript reactjs dom-events


    【解决方案1】:

    reactjs 使用Function.prototype.bind 将上下文绑定到处理程序(否则this 将是undefined)。

    所以幕后发生的事情是这样的:

    element.addEventListener('click', this.handleMouse.bind(this));
    

    因此,您可以看到它是添加到侦听器的另一个函数,而不是 this.handleMouse

    所以在那之后 - 你不能删除它,因为它甚至没有附加。

    react-way 解决方案只是在没有处理程序的情况下再次重新渲染元素,以便反应分离处理程序本身。

    Relevant (?) 反应中的代码:

    /**
     * Binds a method to the component.
     *
     * @param {object} component Component whose method is going to be bound.
     * @param {function} method Method to be bound.
     * @return {function} The bound method.
     */
    function bindAutoBindMethod(component, method) {
      var boundMethod = method.bind(component);
      if (__DEV__) {
        // stripped as irrelevant
      }
      return boundMethod;
    }
    
    /**
     * Binds all auto-bound methods in a component.
     *
     * @param {object} component Component whose method is going to be bound.
     */
    function bindAutoBindMethods(component) {
      var pairs = component.__reactAutoBindPairs;
      for (var i = 0; i < pairs.length; i += 2) {
        var autoBindKey = pairs[i];
        var method = pairs[i + 1];
        component[autoBindKey] = bindAutoBindMethod(
          component,
          method
        );
      }
    }
    

    【讨论】:

    • 如果是这种情况,我将不得不将参数传递给该 onclick 回调函数。但我还需要传递给回调的事件对象。 self.handleMouse.bind(self, myParameter),如何接收事件对象??我使用绑定,所以它不会自动运行该功能,直到它被点击。谢谢
    • 好吧,你只是不需要那个 - 只需在没有处理程序的情况下重新渲染元素,reactjs 就会为你分离它。
    • 我不确定在我的情况下是否可行。我在你的名字下的原始帖子中做了一些细节内部工作,你能看看吗?谢谢
    • 我查过了,看不懂。在每种情况下,重新渲染绝对是可能的:这就是 reactjs 开发人员应该做的,这就是 reactjs 的设计目的。
    • 我的错我找不到方法来找出点击了哪个 li,所以我无法触发会导致重新渲染的状态更改。但我只是意识到我可以使用 event.currentTarget.id 获取元素的 id。现在我能够更改 handleMouse 中的状态,从而导致重新渲染。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2016-12-28
    • 2014-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    • 2013-10-02
    • 2018-01-25
    相关资源
    最近更新 更多