Convert createReactClassIntegration-test to createRoot (#27914)
Convert createReactClassIntegration-test to createRoot
Jan Kassens committed
Jan 9, 2024 at 15:30 UTC
9723093df319f06886fe488d6d88ff615a3e8fc3
1 file changed
+108
-56
packages/react/src/__tests__/createReactClassIntegration-test.js
+108
-56
@@ -9,18 +9,21 @@
9
10
'use strict';
11
12
+let act;
13
+
14
let PropTypes;
15
let React;
14
-let ReactDOM;
16
+let ReactDOMClient;
17
let ReactTestUtils;
18
let createReactClass;
19
20
describe('create-react-class-integration', () => {
21
beforeEach(() => {
22
jest.resetModules();
23
+ ({act} = require('internal-test-utils'));
24
PropTypes = require('prop-types');
25
React = require('react');
23
- ReactDOM = require('react-dom');
26
+ ReactDOMClient = require('react-dom/client');
27
ReactTestUtils = require('react-dom/test-utils');
28
createReactClass = require('create-react-class/factory')(
29
React.Component,
@@ -292,7 +295,7 @@ describe('create-react-class-integration', () => {
295
});
296
297
// @gate !disableLegacyContext
295
- it('renders based on context getInitialState', () => {
298
+ it('renders based on context getInitialState', async () => {
299
const Foo = createReactClass({
300
contextTypes: {
301
className: PropTypes.string,
@@ -318,7 +321,10 @@ describe('create-react-class-integration', () => {
321
});
322
323
const container = document.createElement('div');
321
- ReactDOM.render(<Outer />, container);
324
+ const root = ReactDOMClient.createRoot(container);
325
+ await act(() => {
326
+ root.render(<Outer />);
327
+ });
328
expect(container.firstChild.className).toBe('foo');
329
});
330
@@ -388,7 +394,7 @@ describe('create-react-class-integration', () => {
394
expect(ops).toEqual(['Render: 0', 'Render: 1', 'Callback: 1']);
395
});
396
391
- it('getDerivedStateFromProps updates state when props change', () => {
397
+ it('getDerivedStateFromProps updates state when props change', async () => {
398
const Component = createReactClass({
399
getInitialState() {
400
return {
@@ -404,23 +410,26 @@ describe('create-react-class-integration', () => {
410
});
411
412
const container = document.createElement('div');
407
- const instance = ReactDOM.render(
408
- <div>
409
- <Component incrementBy={0} />
410
- </div>,
411
- container,
412
- );
413
- expect(instance.textContent).toEqual('count:1');
414
- ReactDOM.render(
415
- <div>
416
- <Component incrementBy={2} />
417
- </div>,
418
- container,
419
- );
420
- expect(instance.textContent).toEqual('count:3');
413
+ const root = ReactDOMClient.createRoot(container);
414
+ await act(() => {
415
+ root.render(
416
+ <div>
417
+ <Component incrementBy={0} />
418
+ </div>,
419
+ );
420
+ });
421
+ expect(container.firstChild.textContent).toEqual('count:1');
422
+ await act(() => {
423
+ root.render(
424
+ <div>
425
+ <Component incrementBy={2} />
426
+ </div>,
427
+ );
428
+ });
429
+ expect(container.firstChild.textContent).toEqual('count:3');
430
});
431
423
- it('should support the new static getDerivedStateFromProps method', () => {
432
+ it('should support the new static getDerivedStateFromProps method', async () => {
433
let instance;
434
const Component = createReactClass({
435
statics: {
@@ -438,11 +447,14 @@ describe('create-react-class-integration', () => {
447
return null;
448
},
449
});
441
- ReactDOM.render(<Component />, document.createElement('div'));
450
+ const root = ReactDOMClient.createRoot(document.createElement('div'));
451
+ await act(() => {
452
+ root.render(<Component />);
453
+ });
454
expect(instance.state.foo).toBe('bar');
455
});
456
445
- it('warns if getDerivedStateFromProps is not static', () => {
457
+ it('warns if getDerivedStateFromProps is not static', async () => {
458
const Foo = createReactClass({
459
displayName: 'Foo',
460
getDerivedStateFromProps() {
@@ -452,15 +464,18 @@ describe('create-react-class-integration', () => {
464
return <div />;
465
},
466
});
455
- expect(() =>
456
- ReactDOM.render(<Foo foo="foo" />, document.createElement('div')),
457
- ).toErrorDev(
467
+ await expect(async () => {
468
+ const root = ReactDOMClient.createRoot(document.createElement('div'));
469
+ await act(() => {
470
+ root.render(<Foo foo="foo" />);
471
+ });
472
+ }).toErrorDev(
473
'Foo: getDerivedStateFromProps() is defined as an instance method ' +
474
'and will be ignored. Instead, declare it as a static method.',
475
);
476
});
477
463
- it('warns if getDerivedStateFromError is not static', () => {
478
+ it('warns if getDerivedStateFromError is not static', async () => {
479
const Foo = createReactClass({
480
displayName: 'Foo',
481
getDerivedStateFromError() {
@@ -470,15 +485,18 @@ describe('create-react-class-integration', () => {
485
return <div />;
486
},
487
});
473
- expect(() =>
474
- ReactDOM.render(<Foo foo="foo" />, document.createElement('div')),
475
- ).toErrorDev(
488
+ await expect(async () => {
489
+ const root = ReactDOMClient.createRoot(document.createElement('div'));
490
+ await act(() => {
491
+ root.render(<Foo foo="foo" />);
492
+ });
493
+ }).toErrorDev(
494
'Foo: getDerivedStateFromError() is defined as an instance method ' +
495
'and will be ignored. Instead, declare it as a static method.',
496
);
497
});
498
481
- it('warns if getSnapshotBeforeUpdate is static', () => {
499
+ it('warns if getSnapshotBeforeUpdate is static', async () => {
500
const Foo = createReactClass({
501
displayName: 'Foo',
502
statics: {
@@ -490,15 +508,18 @@ describe('create-react-class-integration', () => {
508
return <div />;
509
},
510
});
493
- expect(() =>
494
- ReactDOM.render(<Foo foo="foo" />, document.createElement('div')),
495
- ).toErrorDev(
511
+ await expect(async () => {
512
+ const root = ReactDOMClient.createRoot(document.createElement('div'));
513
+ await act(() => {
514
+ root.render(<Foo foo="foo" />);
515
+ });
516
+ }).toErrorDev(
517
'Foo: getSnapshotBeforeUpdate() is defined as a static method ' +
518
'and will be ignored. Instead, declare it as an instance method.',
519
);
520
});
521
501
- it('should warn if state is not properly initialized before getDerivedStateFromProps', () => {
522
+ it('should warn if state is not properly initialized before getDerivedStateFromProps', async () => {
523
const Component = createReactClass({
524
displayName: 'Component',
525
statics: {
@@ -510,9 +531,12 @@ describe('create-react-class-integration', () => {
531
return null;
532
},
533
});
513
- expect(() =>
514
- ReactDOM.render(<Component />, document.createElement('div')),
515
- ).toErrorDev(
534
+ await expect(async () => {
535
+ const root = ReactDOMClient.createRoot(document.createElement('div'));
536
+ await act(() => {
537
+ root.render(<Component />);
538
+ });
539
+ }).toErrorDev(
540
'`Component` uses `getDerivedStateFromProps` but its initial state is ' +
541
'null. This is not recommended. Instead, define the initial state by ' +
542
'assigning an object to `this.state` in the constructor of `Component`. ' +
@@ -520,7 +544,7 @@ describe('create-react-class-integration', () => {
544
);
545
});
546
523
- it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present', () => {
547
+ it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new static gDSFP is present', async () => {
548
const Component = createReactClass({
549
statics: {
550
getDerivedStateFromProps: function () {
@@ -544,9 +568,12 @@ describe('create-react-class-integration', () => {
568
},
569
});
570
547
- expect(() => {
548
- expect(() => {
549
- ReactDOM.render(<Component />, document.createElement('div'));
571
+ await expect(async () => {
572
+ await expect(async () => {
573
+ const root = ReactDOMClient.createRoot(document.createElement('div'));
574
+ await act(() => {
575
+ root.render(<Component />);
576
+ });
577
}).toErrorDev(
578
'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
579
'Component uses getDerivedStateFromProps() but also contains the following legacy lifecycles:\n' +
@@ -564,10 +591,13 @@ describe('create-react-class-integration', () => {
591
],
592
{withoutStack: true},
593
);
567
- ReactDOM.render(<Component foo={1} />, document.createElement('div'));
594
+ const root = ReactDOMClient.createRoot(document.createElement('div'));
595
+ await act(() => {
596
+ root.render(<Component foo={1} />);
597
+ });
598
});
599
570
- it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new getSnapshotBeforeUpdate is present', () => {
600
+ it('should not invoke deprecated lifecycles (cWM/cWRP/cWU) if new getSnapshotBeforeUpdate is present', async () => {
601
const Component = createReactClass({
602
getSnapshotBeforeUpdate: function () {
603
return null;
@@ -587,9 +617,12 @@ describe('create-react-class-integration', () => {
617
},
618
});
619
590
- expect(() => {
591
- expect(() => {
592
- ReactDOM.render(<Component />, document.createElement('div'));
620
+ await expect(async () => {
621
+ await expect(async () => {
622
+ const root = ReactDOMClient.createRoot(document.createElement('div'));
623
+ await act(() => {
624
+ root.render(<Component />);
625
+ });
626
}).toErrorDev(
627
'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' +
628
'Component uses getSnapshotBeforeUpdate() but also contains the following legacy lifecycles:\n' +
@@ -607,10 +640,13 @@ describe('create-react-class-integration', () => {
640
],
641
{withoutStack: true},
642
);
610
- ReactDOM.render(<Component foo={1} />, document.createElement('div'));
643
+ await act(() => {
644
+ const root2 = ReactDOMClient.createRoot(document.createElement('div'));
645
+ root2.render(<Component foo={1} />);
646
+ });
647
});
648
613
- it('should invoke both deprecated and new lifecycles if both are present', () => {
649
+ it('should invoke both deprecated and new lifecycles if both are present', async () => {
650
const log = [];
651
652
const Component = createReactClass({
@@ -641,8 +677,13 @@ describe('create-react-class-integration', () => {
677
},
678
});
679
644
- const div = document.createElement('div');
645
- expect(() => ReactDOM.render(<Component foo="bar" />, div)).toWarnDev(
680
+ const root = ReactDOMClient.createRoot(document.createElement('div'));
681
+
682
+ await expect(async () => {
683
+ await act(() => {
684
+ root.render(<Component foo="bar" />);
685
+ });
686
+ }).toWarnDev(
687
[
688
'componentWillMount has been renamed',
689
'componentWillReceiveProps has been renamed',
@@ -654,7 +695,9 @@ describe('create-react-class-integration', () => {
695
696
log.length = 0;
697
657
- ReactDOM.render(<Component foo="baz" />, div);
698
+ await act(() => {
699
+ root.render(<Component foo="baz" />);
700
+ });
701
expect(log).toEqual([
702
'componentWillReceiveProps',
703
'UNSAFE_componentWillReceiveProps',
@@ -663,7 +706,7 @@ describe('create-react-class-integration', () => {
706
]);
707
});
708
666
- it('isMounted works', () => {
709
+ it('isMounted works', async () => {
710
const ops = [];
711
let instance;
712
const Component = createReactClass({
@@ -716,9 +759,13 @@ describe('create-react-class-integration', () => {
759
},
760
});
761
719
- const container = document.createElement('div');
762
+ const root = ReactDOMClient.createRoot(document.createElement('div'));
763
721
- expect(() => ReactDOM.render(<Component />, container)).toErrorDev(
764
+ await expect(async () => {
765
+ await act(() => {
766
+ root.render(<Component />);
767
+ });
768
+ }).toErrorDev(
769
'Warning: MyComponent: isMounted is deprecated. Instead, make sure to ' +
770
'clean up subscriptions and pending requests in componentWillUnmount ' +
771
'to prevent memory leaks.',
@@ -726,9 +773,14 @@ describe('create-react-class-integration', () => {
773
);
774
775
// Dedupe
729
- ReactDOM.render(<Component />, container);
776
731
- ReactDOM.unmountComponentAtNode(container);
777
+ await act(() => {
778
+ root.render(<Component />);
779
+ });
780
+
781
+ await act(() => {
782
+ root.unmount();
783
+ });
784
instance.log('after unmount');
785
expect(ops).toEqual([
786
'getInitialState: false',