@@ -28,6 +28,7 @@ describe('ReactDOMSuspensePlaceholder', () => {
2828 ReactCache = require ( 'react-cache' ) ;
2929 Suspense = React . Suspense ;
3030 container = document . createElement ( 'div' ) ;
31+ document . body . appendChild ( container ) ;
3132
3233 TextResource = ReactCache . unstable_createResource ( ( [ text , ms = 0 ] ) => {
3334 return new Promise ( ( resolve , reject ) =>
@@ -38,6 +39,10 @@ describe('ReactDOMSuspensePlaceholder', () => {
3839 } , ( [ text , ms ] ) => text ) ;
3940 } ) ;
4041
42+ afterEach ( ( ) => {
43+ document . body . removeChild ( container ) ;
44+ } ) ;
45+
4146 function advanceTimers ( ms ) {
4247 // Note: This advances Jest's virtual time but not React's. Use
4348 // ReactNoop.expire for that.
@@ -157,4 +162,64 @@ describe('ReactDOMSuspensePlaceholder', () => {
157162 ) ;
158163 } ,
159164 ) ;
165+
166+ // Regression test for https://github.com/facebook/react/issues/14188
167+ it ( 'can call findDOMNode() in a suspended component commit phase' , async ( ) => {
168+ const log = [ ] ;
169+ const Lazy = React . lazy (
170+ ( ) =>
171+ new Promise ( resolve =>
172+ resolve ( {
173+ default ( ) {
174+ return 'lazy' ;
175+ } ,
176+ } ) ,
177+ ) ,
178+ ) ;
179+
180+ class Child extends React . Component {
181+ componentDidMount ( ) {
182+ log . push ( 'cDM ' + this . props . id ) ;
183+ ReactDOM . findDOMNode ( this ) ;
184+ }
185+ componentDidUpdate ( ) {
186+ log . push ( 'cDU ' + this . props . id ) ;
187+ ReactDOM . findDOMNode ( this ) ;
188+ }
189+ render ( ) {
190+ return 'child' ;
191+ }
192+ }
193+
194+ const buttonRef = React . createRef ( ) ;
195+ class App extends React . Component {
196+ state = {
197+ suspend : false ,
198+ } ;
199+ handleClick = ( ) => {
200+ this . setState ( { suspend : true } ) ;
201+ } ;
202+ render ( ) {
203+ return (
204+ < React . Suspense fallback = "Loading" >
205+ < Child id = "first" />
206+ < button ref = { buttonRef } onClick = { this . handleClick } >
207+ Suspend
208+ </ button >
209+ < Child id = "second" />
210+ { this . state . suspend && < Lazy /> }
211+ </ React . Suspense >
212+ ) ;
213+ }
214+ }
215+
216+ ReactDOM . render ( < App /> , container ) ;
217+
218+ expect ( log ) . toEqual ( [ 'cDM first' , 'cDM second' ] ) ;
219+ log . length = 0 ;
220+
221+ buttonRef . current . dispatchEvent ( new MouseEvent ( 'click' , { bubbles : true } ) ) ;
222+ await Lazy ;
223+ expect ( log ) . toEqual ( [ 'cDU first' , 'cDU second' ] ) ;
224+ } ) ;
160225} ) ;
0 commit comments