Skip to content

Commit 243d991

Browse files
author
Martin Brecht-Precht
committed
Extended the event listener handling. The useCustomDomEventListener function now returns a closure that allows you to easily remove the listener by calling the closure.
1 parent 9107665 commit 243d991

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

readme.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,30 @@ return (
9898
);
9999
```
100100

101+
`useCustomDomEventListener` returns a closure that allows you to remove the added event listener if required.
102+
103+
```typescript
104+
import { useRef } from 'react';
105+
import { useCustomDomEventListener } from '@chroma-x/react-custom-dom-events';
106+
107+
const listenerElement = useRef(null);
108+
109+
const removeListener = useCustomDomEventListener<string>(listenerElement, 'myCustomEvent', (event): void => {
110+
event.stopPropagation();
111+
console.debug(event.detail);
112+
});
113+
114+
const handleClick = (): void => {
115+
removeListener();
116+
};
117+
118+
return (
119+
<div ref={listenerElement}>
120+
<button onClick={handleClick}>Remove event listener</button>
121+
</div>
122+
);
123+
```
124+
101125
`useCustomDomEventListener` makes use of the useEffect hook, so it can be used in functional components only.
102126

103127
There is no need to handle the removal of the event listener. Listeners are removed on component unmount by reacts useEffect destructor.

src/index.tsx

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,38 @@ export function useCustomDomEventListener<T = any>(
1818
event: string,
1919
eventHandler: (event: TypedCustomDomEvent<T>) => void,
2020
options?: AddEventListenerOptions
21-
): void {
21+
): () => void {
22+
// Prepare the handler
23+
const handleEvent = (customEvent: CustomEvent | Event) => {
24+
eventHandler(customEvent as TypedCustomDomEvent<T>);
25+
};
26+
27+
// Prepare the listener options
28+
const listenerOptions: AddEventListenerOptions | false = options ?? false;
29+
30+
// Invoke useEffect to async add the listener
2231
useEffect(() => {
2332
const listenerTargetElement = unwrapDomElement(listenerTarget);
2433
if (listenerTargetElement === null) {
2534
return;
2635
}
2736

28-
const handleEvent = (customEvent: CustomEvent | Event) => {
29-
eventHandler(customEvent as TypedCustomDomEvent<T>);
30-
};
31-
32-
const listenerOptions: AddEventListenerOptions | false = options ?? false;
3337
listenerTargetElement.addEventListener(event, handleEvent, listenerOptions);
3438

39+
// eslint-disable-next-line consistent-return
3540
return () => {
3641
listenerTargetElement.removeEventListener(event, handleEvent, listenerOptions);
3742
};
3843
});
44+
45+
// Return the listener removal closure
46+
return () => {
47+
const listenerTargetElement = unwrapDomElement(listenerTarget);
48+
if (listenerTargetElement === null) {
49+
return;
50+
}
51+
listenerTargetElement.removeEventListener(event, handleEvent, listenerOptions);
52+
};
3953
}
4054

4155
export function emitCustomDomEvent<T = any>(

0 commit comments

Comments
 (0)