removeEventListener() should be called with a correct listener
- BAD_REMOVE_EVENT_LISTENER
- Error
- Medium
- No tags
This rule applies when removeEventListener() is called with a wrong listener.
The removeEventListener() method can only remove the exact function instance that was added at the addEventListener() call. So, nothing occurs in the following cases:
- When a newly created function is passed. This case is likely caused by a programmer's misunderstanding that if two functions have the same textual body, they will represent the same function instance. Also, it could result from the
Function.prototype.bind()that always generates a new function instance. - When the return value of
addEventListener()is passed. Note that the return value ofaddEventListener()' is not the added listener function, but anundefined` value.
Unremoved listeners would cause a memory leak. To fix this problem, you should keep the reference of the added handler and use it as the argument of the removeEventListener().
Noncompliant Code Example
View with compliant examples side by side// Example 1
export class Foo {
update() {
doUpdate(this);
}
addHandlers() {
document.addEventListener("keydown", () => foo());
document.addEventListener("click", this.update.bind(this));
}
removeHandlers() {
document.removeEventListener("keydown", () => foo()); // BAD_REMOVE_EVENT_LISTENER alarm
document.removeEventListener("click", this.update.bind(this)); // BAD_REMOVE_EVENT_LISTENER alarm
}
}
// Example 2
export class Bar {
update = () => {
doUpdate(this);
}
init() {
this.handler = document.addEventListener("click", this.update);
}
destroy() {
document.removeEventListener("click", this.handler); // BAD_REMOVE_EVENT_LISTENER alarm
}
}Compliant Code Example
View with noncompliant examples side by side// Example 1
export class Foo {
keydownHandler() {
foo();
}
update = () => {
doUpdate(this);
}
addHandlers() {
document.addEventListener("keydown", this.keydownHandler);
document.addEventListener("click", this.update);
}
removeHandlers() {
document.removeEventListener("keydown", this.keydownHandler);
document.removeEventListener("click", this.update);
}
}
// Example 2
export class Bar {
update = () => {
doUpdate(this);
}
init() {
document.addEventListener("click", this.update);
}
destroy() {
document.removeEventListener("click", this.update);
}
}Version
This rule was introduced in DeepScan 1.28.0.