@samitouri / QOS-React-1 / commits / 72411c45f9

Convert refs-destruction to createRoot (#28011)

Ricky committed Jan 24, 2024 at 14:22 UTC 72411c45f94565c30215b51cbadb16fcc3479d37
1 file changed +69 -38
packages/react-dom/src/__tests__/refs-destruction-test.js
+69 -38
@@ -11,9 +11,12 @@
11
12 let React;
13 let ReactDOM;
14 +let ReactDOMClient;
15 let ReactTestUtils;
15 -
16 let TestComponent;
17 +let act;
18 +let theInnerDivRef;
19 +let theInnerClassComponentRef;
20
21 describe('refs-destruction', () => {
22 beforeEach(() => {
@@ -21,7 +24,9 @@ describe('refs-destruction', () => {
24
25 React = require('react');
26 ReactDOM = require('react-dom');
27 + ReactDOMClient = require('react-dom/client');
28 ReactTestUtils = require('react-dom/test-utils');
29 + act = require('internal-test-utils').act;
30
31 class ClassComponent extends React.Component {
32 render() {
@@ -30,8 +35,11 @@ describe('refs-destruction', () => {
35 }
36
37 TestComponent = class extends React.Component {
33 - theInnerDivRef = React.createRef();
34 - theInnerClassComponentRef = React.createRef();
38 + constructor(props) {
39 + super(props);
40 + theInnerDivRef = React.createRef();
41 + theInnerClassComponentRef = React.createRef();
42 + }
43
44 render() {
45 if (this.props.destroy) {
@@ -46,8 +54,8 @@ describe('refs-destruction', () => {
54 } else {
55 return (
56 <div>
49 - <div ref={this.theInnerDivRef} />
50 - <ClassComponent ref={this.theInnerClassComponentRef} />
57 + <div ref={theInnerDivRef} />
58 + <ClassComponent ref={theInnerClassComponentRef} />
59 </div>
60 );
61 }
@@ -55,60 +63,79 @@ describe('refs-destruction', () => {
63 };
64 });
65
58 - it('should remove refs when destroying the parent', () => {
66 + afterEach(() => {
67 + theInnerClassComponentRef = null;
68 + theInnerDivRef = null;
69 + });
70 +
71 + it('should remove refs when destroying the parent', async () => {
72 const container = document.createElement('div');
60 - const testInstance = ReactDOM.render(<TestComponent />, container);
73 + const root = ReactDOMClient.createRoot(container);
74 + await act(async () => {
75 + root.render(<TestComponent />);
76 + });
77
62 - expect(
63 - ReactTestUtils.isDOMComponent(testInstance.theInnerDivRef.current),
64 - ).toBe(true);
65 - expect(testInstance.theInnerClassComponentRef.current).toBeTruthy();
78 + expect(ReactTestUtils.isDOMComponent(theInnerDivRef.current)).toBe(true);
79 + expect(theInnerClassComponentRef.current).toBeTruthy();
80
67 - ReactDOM.unmountComponentAtNode(container);
81 + root.unmount();
82
69 - expect(testInstance.theInnerDivRef.current).toBe(null);
70 - expect(testInstance.theInnerClassComponentRef.current).toBe(null);
83 + expect(theInnerDivRef.current).toBe(null);
84 + expect(theInnerClassComponentRef.current).toBe(null);
85 });
86
73 - it('should remove refs when destroying the child', () => {
87 + it('should remove refs when destroying the child', async () => {
88 const container = document.createElement('div');
75 - const testInstance = ReactDOM.render(<TestComponent />, container);
76 - expect(
77 - ReactTestUtils.isDOMComponent(testInstance.theInnerDivRef.current),
78 - ).toBe(true);
79 - expect(testInstance.theInnerClassComponentRef.current).toBeTruthy();
89 + const root = ReactDOMClient.createRoot(container);
90 + await act(async () => {
91 + root.render(<TestComponent />);
92 + });
93 +
94 + expect(ReactTestUtils.isDOMComponent(theInnerDivRef.current)).toBe(true);
95 + expect(theInnerClassComponentRef.current).toBeTruthy();
96
81 - ReactDOM.render(<TestComponent destroy={true} />, container);
97 + await act(async () => {
98 + root.render(<TestComponent destroy={true} />);
99 + });
100
83 - expect(testInstance.theInnerDivRef.current).toBe(null);
84 - expect(testInstance.theInnerClassComponentRef.current).toBe(null);
101 + expect(theInnerDivRef.current).toBe(null);
102 + expect(theInnerClassComponentRef.current).toBe(null);
103 });
104
87 - it('should remove refs when removing the child ref attribute', () => {
105 + it('should remove refs when removing the child ref attribute', async () => {
106 const container = document.createElement('div');
89 - const testInstance = ReactDOM.render(<TestComponent />, container);
107 + const root = ReactDOMClient.createRoot(container);
108 + await act(async () => {
109 + root.render(<TestComponent />);
110 + });
111
91 - expect(
92 - ReactTestUtils.isDOMComponent(testInstance.theInnerDivRef.current),
93 - ).toBe(true);
94 - expect(testInstance.theInnerClassComponentRef.current).toBeTruthy();
112 + expect(ReactTestUtils.isDOMComponent(theInnerDivRef.current)).toBe(true);
113 + expect(theInnerClassComponentRef.current).toBeTruthy();
114
96 - ReactDOM.render(<TestComponent removeRef={true} />, container);
115 + await act(async () => {
116 + root.render(<TestComponent removeRef={true} />);
117 + });
118
98 - expect(testInstance.theInnerDivRef.current).toBe(null);
99 - expect(testInstance.theInnerClassComponentRef.current).toBe(null);
119 + expect(theInnerDivRef.current).toBe(null);
120 + expect(theInnerClassComponentRef.current).toBe(null);
121 });
122
102 - it('should not error when destroying child with ref asynchronously', () => {
123 + it('should not error when destroying child with ref asynchronously', async () => {
124 + let nestedRoot;
125 class Modal extends React.Component {
126 componentDidMount() {
127 this.div = document.createElement('div');
128 + nestedRoot = ReactDOMClient.createRoot(this.div);
129 document.body.appendChild(this.div);
130 this.componentDidUpdate();
131 }
132
133 componentDidUpdate() {
111 - ReactDOM.render(<div>{this.props.children}</div>, this.div);
134 + setTimeout(() => {
135 + ReactDOM.flushSync(() => {
136 + nestedRoot.render(<div>{this.props.children}</div>);
137 + });
138 + }, 0);
139 }
140
141 componentWillUnmount() {
@@ -116,7 +143,7 @@ describe('refs-destruction', () => {
143 // some async animation
144 setTimeout(function () {
145 expect(function () {
119 - ReactDOM.unmountComponentAtNode(self.div);
146 + nestedRoot.unmount();
147 }).not.toThrow();
148 document.body.removeChild(self.div);
149 }, 0);
@@ -144,8 +171,12 @@ describe('refs-destruction', () => {
171 }
172
173 const container = document.createElement('div');
147 - ReactDOM.render(<App />, container);
148 - ReactDOM.render(<App hidden={true} />, container);
149 - jest.runAllTimers();
174 + const root = ReactDOMClient.createRoot(container);
175 + await act(async () => {
176 + root.render(<App />);
177 + });
178 + await act(async () => {
179 + root.render(<App hidden={true} />);
180 + });
181 });
182 });