12
12
let PropTypes ;
13
13
let React ;
14
14
let ReactDOMClient ;
15
- let ReactTestUtils ;
16
15
let act ;
17
16
18
17
function FunctionComponent ( props ) {
@@ -26,7 +25,6 @@ describe('ReactFunctionComponent', () => {
26
25
React = require ( 'react' ) ;
27
26
ReactDOMClient = require ( 'react-dom/client' ) ;
28
27
act = require ( 'internal-test-utils' ) . act ;
29
- ReactTestUtils = require ( 'react-dom/test-utils' ) ;
30
28
} ) ;
31
29
32
30
it ( 'should render stateless component' , async ( ) => {
@@ -161,25 +159,33 @@ describe('ReactFunctionComponent', () => {
161
159
) ;
162
160
} ) ;
163
161
164
- it ( 'should not throw when stateless component returns undefined' , ( ) => {
162
+ it ( 'should not throw when stateless component returns undefined' , async ( ) => {
165
163
function NotAComponent ( ) { }
166
- expect ( function ( ) {
167
- ReactTestUtils . renderIntoDocument (
168
- < div >
169
- < NotAComponent />
170
- </ div > ,
171
- ) ;
172
- } ) . not . toThrowError ( ) ;
164
+ const container = document . createElement ( 'div' ) ;
165
+ const root = ReactDOMClient . createRoot ( container ) ;
166
+ await expect (
167
+ act ( ( ) => {
168
+ root . render (
169
+ < div >
170
+ < NotAComponent />
171
+ </ div > ,
172
+ ) ;
173
+ } ) ,
174
+ ) . resolves . not . toThrowError ( ) ;
173
175
} ) ;
174
176
175
- it ( 'should throw on string refs in pure functions' , ( ) => {
177
+ it ( 'should throw on string refs in pure functions' , async ( ) => {
176
178
function Child ( ) {
177
179
return < div ref = "me" /> ;
178
180
}
179
181
180
- expect ( function ( ) {
181
- ReactTestUtils . renderIntoDocument ( < Child test = "test" /> ) ;
182
- } ) . toThrowError (
182
+ const container = document . createElement ( 'div' ) ;
183
+ const root = ReactDOMClient . createRoot ( container ) ;
184
+ await expect (
185
+ act ( ( ) => {
186
+ root . render ( < Child test = "test" /> ) ;
187
+ } ) ,
188
+ ) . rejects . toThrowError (
183
189
__DEV__
184
190
? 'Function components cannot have string refs. We recommend using useRef() instead.'
185
191
: // It happens because we don't save _owner in production for
@@ -193,7 +199,7 @@ describe('ReactFunctionComponent', () => {
193
199
) ;
194
200
} ) ;
195
201
196
- it ( 'should warn when given a string ref' , ( ) => {
202
+ it ( 'should warn when given a string ref' , async ( ) => {
197
203
function Indirection ( props ) {
198
204
return < div > { props . children } </ div > ;
199
205
}
@@ -208,9 +214,13 @@ describe('ReactFunctionComponent', () => {
208
214
}
209
215
}
210
216
211
- expect ( ( ) =>
212
- ReactTestUtils . renderIntoDocument ( < ParentUsingStringRef /> ) ,
213
- ) . toErrorDev (
217
+ await expect ( async ( ) => {
218
+ const container = document . createElement ( 'div' ) ;
219
+ const root = ReactDOMClient . createRoot ( container ) ;
220
+ await act ( ( ) => {
221
+ root . render ( < ParentUsingStringRef /> ) ;
222
+ } ) ;
223
+ } ) . toErrorDev (
214
224
'Warning: Function components cannot be given refs. ' +
215
225
'Attempts to access this ref will fail. ' +
216
226
'Did you mean to use React.forwardRef()?\n\n' +
@@ -223,32 +233,36 @@ describe('ReactFunctionComponent', () => {
223
233
) ;
224
234
225
235
// No additional warnings should be logged
226
- ReactTestUtils . renderIntoDocument ( < ParentUsingStringRef /> ) ;
236
+ const container = document . createElement ( 'div' ) ;
237
+ const root = ReactDOMClient . createRoot ( container ) ;
238
+ await act ( ( ) => {
239
+ root . render ( < ParentUsingStringRef /> ) ;
240
+ } ) ;
227
241
} ) ;
228
242
229
- it ( 'should warn when given a function ref' , ( ) => {
243
+ it ( 'should warn when given a function ref and ignore them' , async ( ) => {
230
244
function Indirection ( props ) {
231
245
return < div > { props . children } </ div > ;
232
246
}
233
247
248
+ const ref = jest . fn ( ) ;
234
249
class ParentUsingFunctionRef extends React . Component {
235
250
render ( ) {
236
251
return (
237
252
< Indirection >
238
- < FunctionComponent
239
- name = "A"
240
- ref = { arg => {
241
- expect ( arg ) . toBe ( null ) ;
242
- } }
243
- />
253
+ < FunctionComponent name = "A" ref = { ref } />
244
254
</ Indirection >
245
255
) ;
246
256
}
247
257
}
248
258
249
- expect ( ( ) =>
250
- ReactTestUtils . renderIntoDocument ( < ParentUsingFunctionRef /> ) ,
251
- ) . toErrorDev (
259
+ await expect ( async ( ) => {
260
+ const container = document . createElement ( 'div' ) ;
261
+ const root = ReactDOMClient . createRoot ( container ) ;
262
+ await act ( ( ) => {
263
+ root . render ( < ParentUsingFunctionRef /> ) ;
264
+ } ) ;
265
+ } ) . toErrorDev (
252
266
'Warning: Function components cannot be given refs. ' +
253
267
'Attempts to access this ref will fail. ' +
254
268
'Did you mean to use React.forwardRef()?\n\n' +
@@ -259,12 +273,17 @@ describe('ReactFunctionComponent', () => {
259
273
' in Indirection (at **)\n' +
260
274
' in ParentUsingFunctionRef (at **)' ,
261
275
) ;
276
+ expect ( ref ) . not . toHaveBeenCalled ( ) ;
262
277
263
278
// No additional warnings should be logged
264
- ReactTestUtils . renderIntoDocument ( < ParentUsingFunctionRef /> ) ;
279
+ const container = document . createElement ( 'div' ) ;
280
+ const root = ReactDOMClient . createRoot ( container ) ;
281
+ await act ( ( ) => {
282
+ root . render ( < ParentUsingFunctionRef /> ) ;
283
+ } ) ;
265
284
} ) ;
266
285
267
- it ( 'deduplicates ref warnings based on element or owner' , ( ) => {
286
+ it ( 'deduplicates ref warnings based on element or owner' , async ( ) => {
268
287
// When owner uses JSX, we can use exact line location to dedupe warnings
269
288
class AnonymousParentUsingJSX extends React . Component {
270
289
render ( ) {
@@ -274,15 +293,24 @@ describe('ReactFunctionComponent', () => {
274
293
275
294
let instance1 ;
276
295
277
- expect ( ( ) => {
278
- instance1 = ReactTestUtils . renderIntoDocument (
279
- < AnonymousParentUsingJSX /> ,
280
- ) ;
296
+ await expect ( async ( ) => {
297
+ const container = document . createElement ( 'div' ) ;
298
+ const root = ReactDOMClient . createRoot ( container ) ;
299
+
300
+ await act ( ( ) => {
301
+ root . render (
302
+ < AnonymousParentUsingJSX ref = { current => ( instance1 = current ) } /> ,
303
+ ) ;
304
+ } ) ;
281
305
} ) . toErrorDev ( 'Warning: Function components cannot be given refs.' ) ;
282
306
// Should be deduped (offending element is on the same line):
283
307
instance1 . forceUpdate ( ) ;
284
308
// Should also be deduped (offending element is on the same line):
285
- ReactTestUtils . renderIntoDocument ( < AnonymousParentUsingJSX /> ) ;
309
+ let container = document . createElement ( 'div' ) ;
310
+ let root = ReactDOMClient . createRoot ( container ) ;
311
+ await act ( ( ) => {
312
+ root . render ( < AnonymousParentUsingJSX /> ) ;
313
+ } ) ;
286
314
287
315
// When owner doesn't use JSX, and is anonymous, we warn once per internal instance.
288
316
class AnonymousParentNotUsingJSX extends React . Component {
@@ -295,15 +323,23 @@ describe('ReactFunctionComponent', () => {
295
323
}
296
324
297
325
let instance2 ;
298
- expect ( ( ) => {
299
- instance2 = ReactTestUtils . renderIntoDocument (
300
- < AnonymousParentNotUsingJSX /> ,
301
- ) ;
326
+ await expect ( async ( ) => {
327
+ container = document . createElement ( 'div' ) ;
328
+ root = ReactDOMClient . createRoot ( container ) ;
329
+ await act ( ( ) => {
330
+ root . render (
331
+ < AnonymousParentNotUsingJSX ref = { current => ( instance2 = current ) } /> ,
332
+ ) ;
333
+ } ) ;
302
334
} ) . toErrorDev ( 'Warning: Function components cannot be given refs.' ) ;
303
335
// Should be deduped (same internal instance, no additional warnings)
304
336
instance2 . forceUpdate ( ) ;
305
337
// Could not be differentiated (since owner is anonymous and no source location)
306
- ReactTestUtils . renderIntoDocument ( < AnonymousParentNotUsingJSX /> ) ;
338
+ container = document . createElement ( 'div' ) ;
339
+ root = ReactDOMClient . createRoot ( container ) ;
340
+ await act ( ( ) => {
341
+ root . render ( < AnonymousParentNotUsingJSX /> ) ;
342
+ } ) ;
307
343
308
344
// When owner doesn't use JSX, but is named, we warn once per owner name
309
345
class NamedParentNotUsingJSX extends React . Component {
@@ -315,19 +351,29 @@ describe('ReactFunctionComponent', () => {
315
351
}
316
352
}
317
353
let instance3 ;
318
- expect ( ( ) => {
319
- instance3 = ReactTestUtils . renderIntoDocument ( < NamedParentNotUsingJSX /> ) ;
354
+ await expect ( async ( ) => {
355
+ container = document . createElement ( 'div' ) ;
356
+ root = ReactDOMClient . createRoot ( container ) ;
357
+ await act ( ( ) => {
358
+ root . render (
359
+ < NamedParentNotUsingJSX ref = { current => ( instance3 = current ) } /> ,
360
+ ) ;
361
+ } ) ;
320
362
} ) . toErrorDev ( 'Warning: Function components cannot be given refs.' ) ;
321
363
// Should be deduped (same owner name, no additional warnings):
322
364
instance3 . forceUpdate ( ) ;
323
365
// Should also be deduped (same owner name, no additional warnings):
324
- ReactTestUtils . renderIntoDocument ( < NamedParentNotUsingJSX /> ) ;
366
+ container = document . createElement ( 'div' ) ;
367
+ root = ReactDOMClient . createRoot ( container ) ;
368
+ await act ( ( ) => {
369
+ root . render ( < NamedParentNotUsingJSX /> ) ;
370
+ } ) ;
325
371
} ) ;
326
372
327
373
// This guards against a regression caused by clearing the current debug fiber.
328
374
// https://github.com/facebook/react/issues/10831
329
375
// @gate !disableLegacyContext || !__DEV__
330
- it ( 'should warn when giving a function ref with context' , ( ) => {
376
+ it ( 'should warn when giving a function ref with context' , async ( ) => {
331
377
function Child ( ) {
332
378
return null ;
333
379
}
@@ -349,7 +395,13 @@ describe('ReactFunctionComponent', () => {
349
395
}
350
396
}
351
397
352
- expect ( ( ) => ReactTestUtils . renderIntoDocument ( < Parent /> ) ) . toErrorDev (
398
+ await expect ( async ( ) => {
399
+ const container = document . createElement ( 'div' ) ;
400
+ const root = ReactDOMClient . createRoot ( container ) ;
401
+ await act ( ( ) => {
402
+ root . render ( < Parent /> ) ;
403
+ } ) ;
404
+ } ) . toErrorDev (
353
405
'Warning: Function components cannot be given refs. ' +
354
406
'Attempts to access this ref will fail. ' +
355
407
'Did you mean to use React.forwardRef()?\n\n' +
@@ -360,36 +412,40 @@ describe('ReactFunctionComponent', () => {
360
412
) ;
361
413
} ) ;
362
414
363
- it ( 'should provide a null ref' , ( ) => {
364
- function Child ( ) {
365
- return < div /> ;
366
- }
367
-
368
- const comp = ReactTestUtils . renderIntoDocument ( < Child /> ) ;
369
- expect ( comp ) . toBe ( null ) ;
370
- } ) ;
371
-
372
- it ( 'should use correct name in key warning' , ( ) => {
415
+ it ( 'should use correct name in key warning' , async ( ) => {
373
416
function Child ( ) {
374
417
return < div > { [ < span /> ] } </ div > ;
375
418
}
376
419
377
- expect ( ( ) => ReactTestUtils . renderIntoDocument ( < Child /> ) ) . toErrorDev (
420
+ await expect ( async ( ) => {
421
+ const container = document . createElement ( 'div' ) ;
422
+ const root = ReactDOMClient . createRoot ( container ) ;
423
+ await act ( ( ) => {
424
+ root . render ( < Child /> ) ;
425
+ } ) ;
426
+ } ) . toErrorDev (
378
427
'Each child in a list should have a unique "key" prop.\n\n' +
379
428
'Check the render method of `Child`.' ,
380
429
) ;
381
430
} ) ;
382
431
383
432
// TODO: change this test after we deprecate default props support
384
433
// for function components
385
- it ( 'should support default props and prop types' , ( ) => {
434
+ it ( 'should support default props and prop types' , async ( ) => {
386
435
function Child ( props ) {
387
436
return < div > { props . test } </ div > ;
388
437
}
389
438
Child . defaultProps = { test : 2 } ;
390
439
Child . propTypes = { test : PropTypes . string } ;
391
440
392
- expect ( ( ) => ReactTestUtils . renderIntoDocument ( < Child /> ) ) . toErrorDev ( [
441
+ await expect ( async ( ) => {
442
+ const container = document . createElement ( 'div' ) ;
443
+ const root = ReactDOMClient . createRoot ( container ) ;
444
+
445
+ await act ( ( ) => {
446
+ root . render ( < Child /> ) ;
447
+ } ) ;
448
+ } ) . toErrorDev ( [
393
449
'Warning: Child: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.' ,
394
450
'Warning: Failed prop type: Invalid prop `test` of type `number` ' +
395
451
'supplied to `Child`, expected `string`.\n' +
@@ -427,28 +483,46 @@ describe('ReactFunctionComponent', () => {
427
483
expect ( el . textContent ) . toBe ( 'en' ) ;
428
484
} ) ;
429
485
430
- it ( 'should work with arrow functions' , ( ) => {
486
+ it ( 'should work with arrow functions' , async ( ) => {
431
487
let Child = function ( ) {
432
488
return < div /> ;
433
489
} ;
434
490
// Will create a new bound function without a prototype, much like a native
435
491
// arrow function.
436
492
Child = Child . bind ( this ) ;
437
493
438
- expect ( ( ) => ReactTestUtils . renderIntoDocument ( < Child /> ) ) . not . toThrow ( ) ;
494
+ await expect ( async ( ) => {
495
+ const container = document . createElement ( 'div' ) ;
496
+ const root = ReactDOMClient . createRoot ( container ) ;
497
+ await act ( ( ) => {
498
+ root . render ( < Child /> ) ;
499
+ } ) ;
500
+ } ) . not . toThrow ( ) ;
439
501
} ) ;
440
502
441
- it ( 'should allow simple functions to return null' , ( ) => {
503
+ it ( 'should allow simple functions to return null' , async ( ) => {
442
504
const Child = function ( ) {
443
505
return null ;
444
506
} ;
445
- expect ( ( ) => ReactTestUtils . renderIntoDocument ( < Child /> ) ) . not . toThrow ( ) ;
507
+ await expect ( async ( ) => {
508
+ const container = document . createElement ( 'div' ) ;
509
+ const root = ReactDOMClient . createRoot ( container ) ;
510
+ await act ( ( ) => {
511
+ root . render ( < Child /> ) ;
512
+ } ) ;
513
+ } ) . not . toThrow ( ) ;
446
514
} ) ;
447
515
448
- it ( 'should allow simple functions to return false' , ( ) => {
516
+ it ( 'should allow simple functions to return false' , async ( ) => {
449
517
function Child ( ) {
450
518
return false ;
451
519
}
452
- expect ( ( ) => ReactTestUtils . renderIntoDocument ( < Child /> ) ) . not . toThrow ( ) ;
520
+ const container = document . createElement ( 'div' ) ;
521
+ const root = ReactDOMClient . createRoot ( container ) ;
522
+ await expect (
523
+ act ( ( ) => {
524
+ root . render ( < Child /> ) ;
525
+ } ) ,
526
+ ) . resolves . not . toThrow ( ) ;
453
527
} ) ;
454
528
} ) ;
0 commit comments