I am registering a handler (for click event). Before registering the handler, I clear the same handler so as not to register two same handlers.
I am using Webpack's Hot Module Replacement. Every time I change something in the JavaScript source code, part of code registering the handler is rerun.
However, the handler is never removed.
export default class TaskHandlers {
// Called from index.js
registerAddTaskClick(addTaskElementId) {
let element = document.querySelector(`#${addTaskElementId}`);
if (element !== null) {
// Never clears the handler
element.removeEventListener('click', this.handleAddTaskClick);
// Keeps piling on new handlers on every HMR.
element.addEventListener('click', this.handleAddTaskClick);
}
}
handleAddTaskClick(event) {
console.log('Clicked');
}
}
If I run element.removeEventListener()
manually, only the last handler gets removed.
Save the reference to the function so that you remove the same function you're adding, you'll also need to .bind(this)
.
export default class TaskHandlers {
constructor() {
this.element = document.querySelector(`#${addTaskElementId}`);
this.handleAddTaskClick = this.handleAddTaskClick.bind(this);
}
// Called from index.js
registerAddTaskClick(addTaskElementId) {
if (this.element !== null) {
this.element.addEventListener('click', this.handleAddTaskClick);
}
}
handleAddTaskClick(event) {
this.element.removeEventListener('click', this.handleAddTaskClick);
console.log('Clicked');
}
}
Update: Also remove the element when you click it and not before, so that you know that it already has a listener binded.
A solution that might work (if it's really needed to keep the instance after changing the code with HMR) is to save the handler in the window object or a global variable that is not part of the module that's refreshed, it's not ideal but might do the trick for you since it's an exceptional case.