I am currently working on React.js Class component.
I have added listener using addEventListener inside componentDidMount like below.
componentDidMount() {
document.addEventListener('copy', this.copyBlock('copy'));
document.addEventListener('cut', this.copyBlock('cut'));
}
componentWillUnmount() {
document.removeEventListener('copy', this.copyBlock('copy'));
document.removeEventListener('cut', this.copyBlock('cut'));
}
// This is the function that added by addEventListener.
// As you can see, argument copyType is passed to copyBlock function and returns event object.
copyBlock = (copyType: 'copy' | 'cut') => (e: ClipboardEvent) => {
if (e.target !== document.body) {
return;
}
const {
type,
libraryStore: { showUtilBlock },
} = this.props;
BlockUtil.copyBlock(e, copyType);
};
However, here is the problem.
When the component is unmounted, the function is supposed to be removed. However, it is not.
But, When I changed copyBlock function like below, it works. it is removed.
componentDidMount() {
document.addEventListener('copy', this.copyBlock);
}
componentWillUnmount() {
document.removeEventListener('copy', this.copyBlock);
}
copyBlock = (e?: ClipboardEvent) => {
if (e.target !== document.body) {
return;
}
const {
type,
libraryStore: { showUtilBlock },
} = this.props;
BlockUtil.copyBlock(e, 'copy');
};
What is the difference? Why eventListener does not work on the arrow function that returns function?
Because it will create a new event handler every time when you call this.copyBlock()
. Each of them has a different pointer. The event handler that passed in removeEventListener()
should be the same as the event handler passed in addEventListener()
.(Same pointer)
Try this:
constructor() {
this.copy = this.copyBlock('copy');
this.cut = this.copyBlock('cut');
}
componentDidMount() {
document.addEventListener('copy', this.copy);
document.addEventListener('cut', this.cut);
}
componentWillUnmount() {
document.removeEventListener('copy', this.copy);
document.removeEventListener('cut', this.cut);
}