为什么 removeEventListener 对 React 安装的事件处理程序不起作用?
Why does removeEventListener not work on event handlers installed by React?
我有一个 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>
)
}
});
reactjs 使用 Function.prototype.bind
将上下文绑定到处理程序(否则 this
将是 undefined
)。
所以幕后发生的事情是这样的:
element.addEventListener('click', this.handleMouse.bind(this));
因此,如您所见,它是添加到侦听器的另一个功能,而不是 this.handleMouse
。
所以在那之后 - 你不能删除它,因为它甚至没有附加。
react-way 解决方案只是在没有处理程序的情况下再次重新渲染元素,以便 react 分离处理程序本身。
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
);
}
}
我有一个 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>
)
}
});
reactjs 使用 Function.prototype.bind
将上下文绑定到处理程序(否则 this
将是 undefined
)。
所以幕后发生的事情是这样的:
element.addEventListener('click', this.handleMouse.bind(this));
因此,如您所见,它是添加到侦听器的另一个功能,而不是 this.handleMouse
。
所以在那之后 - 你不能删除它,因为它甚至没有附加。
react-way 解决方案只是在没有处理程序的情况下再次重新渲染元素,以便 react 分离处理程序本身。
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
);
}
}