@@ -8,11 +8,6 @@ function WrapperComponent(props) {
8
8
return props . children ;
9
9
}
10
10
11
- function handler ( e ) {
12
- const text = e . currentTarget . innerText ;
13
- alert ( 'You clicked: ' + text ) ;
14
- }
15
-
16
11
const initialState = {
17
12
child : false ,
18
13
parent : false ,
@@ -22,67 +17,133 @@ const initialState = {
22
17
export default function EventListenerCase ( ) {
23
18
const fragmentRef = useRef ( null ) ;
24
19
const [ clickedState , setClickedState ] = useState ( { ...initialState } ) ;
20
+ const [ fragmentEventFired , setFragmentEventFired ] = useState ( false ) ;
21
+ const [ bubblesState , setBubblesState ] = useState ( true ) ;
22
+
23
+ function setClick ( id ) {
24
+ setClickedState ( prev => ( { ...prev , [ id ] : true } ) ) ;
25
+ }
26
+
27
+ function fragmentClickHandler ( e ) {
28
+ setFragmentEventFired ( true ) ;
29
+ }
25
30
26
31
return (
27
32
< TestCase title = "Event Dispatch" >
28
33
< TestCase . Steps >
29
34
< li >
30
- Each div has regular click handlers, you can click each one to observe
31
- the status changing
35
+ Each box has regular click handlers, you can click each one to observe
36
+ the status changing through standard bubbling.
32
37
</ li >
33
38
< li > Clear the clicked state</ li >
34
39
< li >
35
40
Click the "Dispatch click event" button to dispatch a click event on
36
- the Fragment
41
+ the Fragment. The event will be dispatched on the Fragment's parent,
42
+ so the child will not change state.
43
+ </ li >
44
+ < li >
45
+ Click the "Add event listener" button to add a click event listener on
46
+ the Fragment. This registers a handler that will turn the child blue
47
+ on click.
48
+ </ li >
49
+ < li >
50
+ Now click the "Dispatch click event" button again. You can see that it
51
+ will fire the Fragment's event handler in addition to bubbling the
52
+ click from the parent.
53
+ </ li >
54
+ < li >
55
+ If you turn off bubbling, only the Fragment's event handler will be
56
+ called.
37
57
</ li >
38
58
</ TestCase . Steps >
39
59
40
60
< TestCase . ExpectedResult >
41
- Dispatching an event on a Fragment will forward the dispatch to its
42
- parent. You can observe when dispatching that the parent handler is
43
- called in additional to bubbling from there. A delay is added to make
44
- the bubbling more clear.
61
+ < p >
62
+ Dispatching an event on a Fragment will forward the dispatch to its
63
+ parent for the standard case. You can observe when dispatching that
64
+ the parent handler is called in additional to bubbling from there. A
65
+ delay is added to make the bubbling more clear.{ ' ' }
66
+ </ p >
67
+ < p >
68
+ When there have been event handlers added to the Fragment, the
69
+ Fragment's event handler will be called in addition to bubbling from
70
+ the parent. Without bubbling, only the Fragment's event handler will
71
+ be called.
72
+ </ p >
45
73
</ TestCase . ExpectedResult >
46
74
47
75
< Fixture >
48
76
< Fixture . Controls >
77
+ < select
78
+ value = { bubblesState ? 'true' : 'false' }
79
+ onChange = { e => {
80
+ setBubblesState ( e . target . value === 'true' ) ;
81
+ } } >
82
+ < option value = "true" > Bubbles: true</ option >
83
+ < option value = "false" > Bubbles: false</ option >
84
+ </ select >
49
85
< button
50
86
onClick = { ( ) => {
51
87
fragmentRef . current . dispatchEvent (
52
- new MouseEvent ( 'click' , { bubbles : true } )
88
+ new MouseEvent ( 'click' , { bubbles : bubblesState } )
53
89
) ;
54
90
} } >
55
91
Dispatch click event
56
92
</ button >
57
93
< button
58
94
onClick = { ( ) => {
59
95
setClickedState ( { ...initialState } ) ;
96
+ setFragmentEventFired ( false ) ;
60
97
} } >
61
98
Reset clicked state
62
99
</ button >
100
+ < button
101
+ onClick = { ( ) => {
102
+ fragmentRef . current . addEventListener (
103
+ 'click' ,
104
+ fragmentClickHandler
105
+ ) ;
106
+ } } >
107
+ Add event listener
108
+ </ button >
109
+ < button
110
+ onClick = { ( ) => {
111
+ fragmentRef . current . removeEventListener (
112
+ 'click' ,
113
+ fragmentClickHandler
114
+ ) ;
115
+ } } >
116
+ Remove event listener
117
+ </ button >
63
118
</ Fixture . Controls >
64
119
< div
65
- onClick = { ( ) => {
120
+ id = "grandparent"
121
+ onClick = { e => {
66
122
setTimeout ( ( ) => {
67
- setClickedState ( prev => ( { ... prev , grandparent : true } ) ) ;
123
+ setClick ( ' grandparent' ) ;
68
124
} , 200 ) ;
69
125
} }
70
126
className = "card" >
71
127
Fragment grandparent - clicked:{ ' ' }
72
128
{ clickedState . grandparent ? 'true' : 'false' }
73
129
< div
74
- onClick = { ( ) => {
130
+ id = "parent"
131
+ onClick = { e => {
75
132
setTimeout ( ( ) => {
76
- setClickedState ( prev => ( { ... prev , parent : true } ) ) ;
133
+ setClick ( ' parent' ) ;
77
134
} , 100 ) ;
78
135
} }
79
136
className = "card" >
80
137
Fragment parent - clicked: { clickedState . parent ? 'true' : 'false' }
81
138
< Fragment ref = { fragmentRef } >
82
139
< div
140
+ style = { {
141
+ backgroundColor : fragmentEventFired ? 'lightblue' : 'inherit' ,
142
+ } }
143
+ id = "child"
83
144
className = "card"
84
- onClick = { ( ) => {
85
- setClickedState ( prev => ( { ... prev , child : true } ) ) ;
145
+ onClick = { e => {
146
+ setClick ( ' child' ) ;
86
147
} } >
87
148
Fragment child - clicked:{ ' ' }
88
149
{ clickedState . child ? 'true' : 'false' }
0 commit comments