1212describe ( 'ReactDOMComponentTree' , ( ) => {
1313 let React ;
1414 let ReactDOM ;
15- let ReactDOMServer ;
1615 let container ;
1716
1817 beforeEach ( ( ) => {
1918 React = require ( 'react' ) ;
2019 ReactDOM = require ( 'react-dom' ) ;
21- ReactDOMServer = require ( 'react-dom/server' ) ;
2220 container = document . createElement ( 'div' ) ;
2321 document . body . appendChild ( container ) ;
2422 } ) ;
@@ -28,39 +26,41 @@ describe('ReactDOMComponentTree', () => {
2826 container = null ;
2927 } ) ;
3028
31- it ( 'finds nodes for instances' , ( ) => {
32- // This is a little hard to test directly. But refs rely on it -- so we
33- // check that we can find a ref at arbitrary points in the tree, even if
34- // other nodes don't have a ref.
29+ it ( 'finds nodes for instances on events' , ( ) => {
30+ const mouseOverID = 'mouseOverID' ;
31+ const clickID = 'clickID' ;
32+ let currentTargetID = null ;
33+ // the current target of an event is set to result of getNodeFromInstance
34+ // when an event is dispatched so we can test behavior by invoking
35+ // events on elements in the tree and confirming the expected node is
36+ // set as the current target
3537 class Component extends React . Component {
38+ handler = e => {
39+ currentTargetID = e . currentTarget . id ;
40+ } ;
3641 render ( ) {
37- var toRef = this . props . toRef ;
3842 return (
39- < div ref = { toRef === 'div' ? 'target' : null } >
40- < h1 ref = { toRef === 'h1' ? 'target' : null } > hello</ h1 >
41- < p ref = { toRef === 'p' ? 'target' : null } >
42- < input ref = { toRef === 'input' ? 'target' : null } />
43- </ p >
44- goodbye.
43+ < div id = { mouseOverID } onMouseOver = { this . handler } >
44+ < div id = { clickID } onClick = { this . handler } />
4545 </ div >
4646 ) ;
4747 }
4848 }
4949
50- function renderAndGetRef ( toRef ) {
51- // We need to unmount any React components from previous assertions in
52- // this test
53- ReactDOM . unmountComponentAtNode ( container ) ;
54- const elt = < Component toRef = { toRef } /> ;
55- container . innerHTML = ReactDOMServer . renderToString ( elt ) ;
56- const inst = ReactDOM . hydrate ( elt , container ) ;
57- return inst . refs . target . nodeName ;
50+ function simulateMouseEvent ( elem , type ) {
51+ const event = new MouseEvent ( type , {
52+ bubbles : true ,
53+ } ) ;
54+ elem . dispatchEvent ( event ) ;
5855 }
5956
60- expect ( renderAndGetRef ( 'div' ) ) . toBe ( 'DIV' ) ;
61- expect ( renderAndGetRef ( 'h1' ) ) . toBe ( 'H1' ) ;
62- expect ( renderAndGetRef ( 'p' ) ) . toBe ( 'P' ) ;
63- expect ( renderAndGetRef ( 'input' ) ) . toBe ( 'INPUT' ) ;
57+ const component = < Component /> ;
58+ ReactDOM . render ( component , container ) ;
59+ expect ( currentTargetID ) . toBe ( null ) ;
60+ simulateMouseEvent ( document . getElementById ( mouseOverID ) , 'mouseover' ) ;
61+ expect ( currentTargetID ) . toBe ( mouseOverID ) ;
62+ simulateMouseEvent ( document . getElementById ( clickID ) , 'click' ) ;
63+ expect ( currentTargetID ) . toBe ( clickID ) ;
6464 } ) ;
6565
6666 it ( 'finds closest instance for node when an event happens' , ( ) => {
@@ -98,6 +98,48 @@ describe('ReactDOMComponentTree', () => {
9898 expect ( currentTargetID ) . toBe ( closestInstanceID ) ;
9999 } ) ;
100100
101+ it ( 'updates event handlers from fiber props' , ( ) => {
102+ let action = '' ;
103+ let instance ;
104+ const handlerA = ( ) => ( action = 'A' ) ;
105+ const handlerB = ( ) => ( action = 'B' ) ;
106+
107+ function simulateMouseOver ( target ) {
108+ const event = new MouseEvent ( 'mouseover' , {
109+ bubbles : true ,
110+ } ) ;
111+ target . dispatchEvent ( event ) ;
112+ }
113+
114+ class HandlerFlipper extends React . Component {
115+ state = { flip : false } ;
116+ flip ( ) {
117+ this . setState ( { flip : true } ) ;
118+ }
119+ render ( ) {
120+ return (
121+ < div
122+ id = "update"
123+ onMouseOver = { this . state . flip ? handlerB : handlerA }
124+ />
125+ ) ;
126+ }
127+ }
128+
129+ ReactDOM . render (
130+ < HandlerFlipper key = "1" ref = { n => ( instance = n ) } /> ,
131+ container ,
132+ ) ;
133+ const node = container . firstChild ;
134+ simulateMouseOver ( node ) ;
135+ expect ( action ) . toEqual ( 'A' ) ;
136+ action = '' ;
137+ // Render with the other event handler.
138+ instance . flip ( ) ;
139+ simulateMouseOver ( node ) ;
140+ expect ( action ) . toEqual ( 'B' ) ;
141+ } ) ;
142+
101143 it ( 'finds a controlled instance from node and gets its current fiber props' , ( ) => {
102144 const inputID = 'inputID' ;
103145 const startValue = undefined ;
0 commit comments