@@ -111,6 +111,8 @@ var expectClickLogsLengthToBe = function(instance, length) {
111111describe ( 'reactiverefs' , ( ) => {
112112 beforeEach ( ( ) => {
113113 jest . resetModuleRegistry ( ) ;
114+ React = require ( 'React' ) ;
115+ ReactTestUtils = require ( 'ReactTestUtils' ) ;
114116 } ) ;
115117
116118 /**
@@ -152,43 +154,46 @@ describe('reactiverefs', () => {
152154 * Tests that when a ref hops around children, we can track that correctly.
153155 */
154156describe ( 'ref swapping' , ( ) => {
157+ let RefHopsAround ;
155158 beforeEach ( ( ) => {
156159 jest . resetModuleRegistry ( ) ;
157- } ) ;
160+ React = require ( 'React' ) ;
161+ ReactTestUtils = require ( 'ReactTestUtils' ) ;
158162
159- class RefHopsAround extends React . Component {
160- state = { count : 0 } ;
163+ RefHopsAround = class extends React . Component {
164+ state = { count : 0 } ;
161165
162- moveRef = ( ) => {
163- this . setState ( { count : this . state . count + 1 } ) ;
164- } ;
166+ moveRef = ( ) => {
167+ this . setState ( { count : this . state . count + 1 } ) ;
168+ } ;
165169
166- render ( ) {
167- var count = this . state . count ;
168- /**
169- * What we have here, is three divs with refs (div1/2/3), but a single
170- * moving cursor ref `hopRef` that "hops" around the three. We'll call the
171- * `moveRef()` function several times and make sure that the hop ref
172- * points to the correct divs.
173- */
174- return (
175- < div >
176- < div
177- className = "first"
178- ref = { count % 3 === 0 ? 'hopRef' : 'divOneRef' }
179- />
180- < div
181- className = "second"
182- ref = { count % 3 === 1 ? 'hopRef' : 'divTwoRef' }
183- />
184- < div
185- className = "third"
186- ref = { count % 3 === 2 ? 'hopRef' : 'divThreeRef' }
187- />
188- </ div >
189- ) ;
190- }
191- }
170+ render ( ) {
171+ var count = this . state . count ;
172+ /**
173+ * What we have here, is three divs with refs (div1/2/3), but a single
174+ * moving cursor ref `hopRef` that "hops" around the three. We'll call the
175+ * `moveRef()` function several times and make sure that the hop ref
176+ * points to the correct divs.
177+ */
178+ return (
179+ < div >
180+ < div
181+ className = "first"
182+ ref = { count % 3 === 0 ? 'hopRef' : 'divOneRef' }
183+ />
184+ < div
185+ className = "second"
186+ ref = { count % 3 === 1 ? 'hopRef' : 'divTwoRef' }
187+ />
188+ < div
189+ className = "third"
190+ ref = { count % 3 === 2 ? 'hopRef' : 'divThreeRef' }
191+ />
192+ </ div >
193+ ) ;
194+ }
195+ } ;
196+ } ) ;
192197
193198 it ( 'Allow refs to hop around children correctly' , ( ) => {
194199 var refHopsAround = ReactTestUtils . renderIntoDocument ( < RefHopsAround /> ) ;
@@ -284,3 +289,101 @@ describe('ref swapping', () => {
284289 expect ( a . refs [ 1 ] . nodeName ) . toBe ( 'DIV' ) ;
285290 } ) ;
286291} ) ;
292+
293+ describe ( 'string refs between fiber and stack' , ( ) => {
294+ beforeEach ( ( ) => {
295+ jest . resetModuleRegistry ( ) ;
296+ React = require ( 'React' ) ;
297+ ReactTestUtils = require ( 'ReactTestUtils' ) ;
298+ } ) ;
299+
300+ it ( 'attaches, detaches from fiber component with stack layer' , ( ) => {
301+ spyOn ( console , 'error' ) ;
302+ const ReactCurrentOwner = require ( 'ReactCurrentOwner' ) ;
303+ const ReactDOM = require ( 'ReactDOM' ) ;
304+ const ReactDOMFiber = require ( 'ReactDOMFiber' ) ;
305+ const ReactInstanceMap = require ( 'ReactInstanceMap' ) ;
306+ let layerMounted = false ;
307+ class A extends React . Component {
308+ render ( ) {
309+ return < div /> ;
310+ }
311+ componentDidMount ( ) {
312+ // ReactLayeredComponentMixin sets ReactCurrentOwner manually
313+ ReactCurrentOwner . current = ReactInstanceMap . get ( this ) ;
314+ const span = < span ref = "span" /> ;
315+ ReactCurrentOwner . current = null ;
316+
317+ ReactDOM . unstable_renderSubtreeIntoContainer (
318+ this ,
319+ span ,
320+ this . _container = document . createElement ( 'div' ) ,
321+ ( ) => {
322+ expect ( this . refs . span . nodeName ) . toBe ( 'SPAN' ) ;
323+ layerMounted = true ;
324+ }
325+ ) ;
326+ }
327+ componentWillUnmount ( ) {
328+ ReactDOM . unmountComponentAtNode ( this . _container ) ;
329+ }
330+ }
331+ const container = document . createElement ( 'div' ) ;
332+ const a = ReactDOMFiber . render ( < A /> , container ) ;
333+ expect ( a . refs . span ) . toBeTruthy ( ) ;
334+ ReactDOMFiber . unmountComponentAtNode ( container ) ;
335+ expect ( a . refs . span ) . toBe ( undefined ) ;
336+ expect ( layerMounted ) . toBe ( true ) ;
337+ expectDev ( console . error . calls . count ( ) ) . toBe ( 1 ) ;
338+ expectDev ( console . error . calls . argsFor ( 0 ) [ 0 ] ) . toBe (
339+ 'Warning: You are using React DOM Fiber which is an experimental ' +
340+ 'renderer. It is likely to have bugs, breaking changes and is ' +
341+ 'unsupported.'
342+ ) ;
343+ } ) ;
344+
345+ it ( 'attaches, detaches from stack component with fiber layer' , ( ) => {
346+ spyOn ( console , 'error' ) ;
347+ const ReactCurrentOwner = require ( 'ReactCurrentOwner' ) ;
348+ const ReactDOM = require ( 'ReactDOM' ) ;
349+ const ReactDOMFiber = require ( 'ReactDOMFiber' ) ;
350+ const ReactInstanceMap = require ( 'ReactInstanceMap' ) ;
351+ let layerMounted = false ;
352+ class A extends React . Component {
353+ render ( ) {
354+ return < div /> ;
355+ }
356+ componentDidMount ( ) {
357+ // ReactLayeredComponentMixin sets ReactCurrentOwner manually
358+ ReactCurrentOwner . current = ReactInstanceMap . get ( this ) ;
359+ const span = < span ref = "span" /> ;
360+ ReactCurrentOwner . current = null ;
361+
362+ ReactDOMFiber . unstable_renderSubtreeIntoContainer (
363+ this ,
364+ span ,
365+ this . _container = document . createElement ( 'div' ) ,
366+ ( ) => {
367+ expect ( this . refs . span . nodeName ) . toBe ( 'SPAN' ) ;
368+ layerMounted = true ;
369+ }
370+ ) ;
371+ }
372+ componentWillUnmount ( ) {
373+ ReactDOMFiber . unmountComponentAtNode ( this . _container ) ;
374+ }
375+ }
376+ const container = document . createElement ( 'div' ) ;
377+ const a = ReactDOM . render ( < A /> , container ) ;
378+ expect ( a . refs . span ) . toBeTruthy ( ) ;
379+ ReactDOM . unmountComponentAtNode ( container ) ;
380+ expect ( a . refs . span ) . toBe ( undefined ) ;
381+ expect ( layerMounted ) . toBe ( true ) ;
382+ expectDev ( console . error . calls . count ( ) ) . toBe ( 1 ) ;
383+ expectDev ( console . error . calls . argsFor ( 0 ) [ 0 ] ) . toBe (
384+ 'Warning: You are using React DOM Fiber which is an experimental ' +
385+ 'renderer. It is likely to have bugs, breaking changes and is ' +
386+ 'unsupported.'
387+ ) ;
388+ } ) ;
389+ } ) ;
0 commit comments