File tree 3 files changed +70
-3
lines changed
3 files changed +70
-3
lines changed Original file line number Diff line number Diff line change @@ -49,6 +49,18 @@ useCustomEventListener('my-event', (data) => {
49
49
})
50
50
```
51
51
52
+ If using state in listener handler, it's recommended to provide dependency list (same as second parameter of ` useEffect ` )
53
+
54
+ ``` javascript
55
+ useCustomEventListener (
56
+ ' my-event' ,
57
+ (data ) => {
58
+ doSomethingWithDataAndStates (data, state1, state2)
59
+ },
60
+ [state1, state2]
61
+ )
62
+ ```
63
+
52
64
No need to remove event listener, it uses react's useEffect hook to remove listener on component unmount
53
65
54
66
And no need to worry about where component is present in dom, these events can be sent and listened to anywhere
Original file line number Diff line number Diff line change @@ -79,3 +79,56 @@ describe('Test Component', () => {
79
79
expect ( data . textContent ) . toBe ( 'data from hello' )
80
80
} )
81
81
} )
82
+
83
+ describe ( 'useCustomEventListener' , ( ) => {
84
+ interface TestComponentProps {
85
+ evenFired : ( text : string ) => void
86
+ }
87
+
88
+ const TestComponent = ( { evenFired } : TestComponentProps ) => {
89
+ const [ text , setText ] = useState ( 'initial' )
90
+
91
+ useCustomEventListener (
92
+ 'eventFired' ,
93
+ ( ) => {
94
+ evenFired ( text )
95
+ } ,
96
+ [ text ]
97
+ )
98
+
99
+ const handleStateChange = ( ) => setText ( 'changed' )
100
+
101
+ const handleEventFire = ( ) => emitCustomEvent ( 'eventFired' )
102
+
103
+ return (
104
+ < >
105
+ < button data-testid = "state-changer" onClick = { handleStateChange } >
106
+ Change State
107
+ </ button >
108
+ < button data-testid = "fire-event-btn" onClick = { handleEventFire } >
109
+ Fire Event with data
110
+ </ button >
111
+ </ >
112
+ )
113
+ }
114
+ test ( 'its callback having latest state' , ( done ) => {
115
+ render (
116
+ < TestComponent
117
+ evenFired = { ( text : string ) => {
118
+ try {
119
+ expect ( text ) . toBe ( 'changed' )
120
+ done ( )
121
+ } catch ( cause ) {
122
+ done ( cause )
123
+ }
124
+ } }
125
+ />
126
+ )
127
+
128
+ const stateChangerBtn = screen . getByTestId ( 'state-changer' )
129
+ userEvent . click ( stateChangerBtn )
130
+
131
+ const fireBtn = screen . getByTestId ( 'fire-event-btn' )
132
+ userEvent . click ( fireBtn )
133
+ } )
134
+ } )
Original file line number Diff line number Diff line change 1
- import { useEffect } from 'react'
1
+ import { DependencyList , useEffect } from 'react'
2
2
3
3
let targetElement : undefined | HTMLDivElement
4
4
@@ -12,9 +12,11 @@ function getElement() {
12
12
13
13
export function useCustomEventListener < T > (
14
14
eventName : string ,
15
- eventHandler : ( data : T ) => void
15
+ eventHandler : ( data : T ) => void ,
16
+ deps ?: DependencyList
16
17
) : ( el : HTMLElement | null ) => void {
17
18
let element : HTMLElement | null
19
+
18
20
useEffect ( ( ) => {
19
21
element = element || getElement ( )
20
22
const handleEvent = ( event : CustomEvent | Event ) => {
@@ -27,7 +29,7 @@ export function useCustomEventListener<T>(
27
29
return ( ) => {
28
30
element ?. removeEventListener ( eventName , handleEvent , false )
29
31
}
30
- } , [ ] )
32
+ } , deps )
31
33
32
34
return ( el : HTMLElement | null ) => {
33
35
element = el
You can’t perform that action at this time.
0 commit comments