Convert ReactComponentLifeycle to createRoot (#28178)
Sebastian Silbermann committed
Feb 2, 2024 at 09:14 UTC
e9c13cde644753e554c060bc71fd57077288ae35
1 file changed
+69
-26
packages/react-dom/src/__tests__/ReactComponentLifeCycle-test.js
+69
-26
@@ -113,9 +113,21 @@ describe('ReactComponentLifeCycle', () => {
113
}
114
115
const element = <StatefulComponent />;
116
- const firstInstance = ReactDOM.render(element, container);
117
- ReactDOM.unmountComponentAtNode(container);
118
- const secondInstance = ReactDOM.render(element, container);
116
+ let root = ReactDOMClient.createRoot(container);
117
+ await act(() => {
118
+ root.render(element);
119
+ });
120
+
121
+ const firstInstance = container.firstChild;
122
+ await act(() => {
123
+ root.unmount();
124
+ });
125
+ root = ReactDOMClient.createRoot(container);
126
+ await act(() => {
127
+ root.render(element);
128
+ });
129
+
130
+ const secondInstance = container.firstChild;
131
expect(firstInstance).not.toBe(secondInstance);
132
});
133
@@ -123,7 +135,7 @@ describe('ReactComponentLifeCycle', () => {
135
* If a state update triggers rerendering that in turn fires an onDOMReady,
136
* that second onDOMReady should not fail.
137
*/
126
- it('it should fire onDOMReady when already in onDOMReady', () => {
138
+ it('it should fire onDOMReady when already in onDOMReady', async () => {
139
const _testJournal = [];
140
141
class Child extends React.Component {
@@ -161,7 +173,13 @@ describe('ReactComponentLifeCycle', () => {
173
}
174
}
175
164
- ReactTestUtils.renderIntoDocument(<SwitcherParent />);
176
+ const container = document.createElement('div');
177
+ const root = ReactDOMClient.createRoot(container);
178
+
179
+ await act(() => {
180
+ root.render(<SwitcherParent />);
181
+ });
182
+
183
expect(_testJournal).toEqual([
184
'SwitcherParent:getInitialState',
185
'SwitcherParent:onDOMReady',
@@ -205,7 +223,7 @@ describe('ReactComponentLifeCycle', () => {
223
}).not.toThrow();
224
});
225
208
- it("warns if setting 'this.state = props'", () => {
226
+ it("warns if setting 'this.state = props'", async () => {
227
class StatefulComponent extends React.Component {
228
constructor(props, context) {
229
super(props, context);
@@ -216,8 +234,12 @@ describe('ReactComponentLifeCycle', () => {
234
}
235
}
236
219
- expect(() => {
220
- ReactTestUtils.renderIntoDocument(<StatefulComponent />);
237
+ const container = document.createElement('div');
238
+ const root = ReactDOMClient.createRoot(container);
239
+ await expect(async () => {
240
+ await act(() => {
241
+ root.render(<StatefulComponent />);
242
+ });
243
}).toErrorDev(
244
'StatefulComponent: It is not recommended to assign props directly to state ' +
245
"because updates to props won't be reflected in state. " +
@@ -225,7 +247,7 @@ describe('ReactComponentLifeCycle', () => {
247
);
248
});
249
228
- it('should not allow update state inside of getInitialState', () => {
250
+ it('should not allow update state inside of getInitialState', async () => {
251
class StatefulComponent extends React.Component {
252
constructor(props, context) {
253
super(props, context);
@@ -239,8 +261,12 @@ describe('ReactComponentLifeCycle', () => {
261
}
262
}
263
242
- expect(() => {
243
- ReactTestUtils.renderIntoDocument(<StatefulComponent />);
264
+ let container = document.createElement('div');
265
+ let root = ReactDOMClient.createRoot(container);
266
+ await expect(async () => {
267
+ await act(() => {
268
+ root.render(<StatefulComponent />);
269
+ });
270
}).toErrorDev(
271
"Warning: Can't call setState on a component that is not yet mounted. " +
272
'This is a no-op, but it might indicate a bug in your application. ' +
@@ -248,11 +274,14 @@ describe('ReactComponentLifeCycle', () => {
274
'class property with the desired state in the StatefulComponent component.',
275
);
276
251
- // Check deduplication; (no extra warnings should be logged).
252
- ReactTestUtils.renderIntoDocument(<StatefulComponent />);
277
+ container = document.createElement('div');
278
+ root = ReactDOMClient.createRoot(container);
279
+ await act(() => {
280
+ root.render(<StatefulComponent />);
281
+ });
282
});
283
255
- it('should correctly determine if a component is mounted', () => {
284
+ it('should correctly determine if a component is mounted', async () => {
285
class Component extends React.Component {
286
_isMounted() {
287
// No longer a public API, but we can test that it works internally by
@@ -271,15 +300,20 @@ describe('ReactComponentLifeCycle', () => {
300
}
301
}
302
274
- const element = <Component />;
303
+ let instance;
304
+ const element = <Component ref={current => (instance = current)} />;
305
276
- expect(() => {
277
- const instance = ReactTestUtils.renderIntoDocument(element);
278
- expect(instance._isMounted()).toBeTruthy();
306
+ const container = document.createElement('div');
307
+ const root = ReactDOMClient.createRoot(container);
308
+ await expect(async () => {
309
+ await act(() => {
310
+ root.render(element);
311
+ });
312
}).toErrorDev('Component is accessing isMounted inside its render()');
313
+ expect(instance._isMounted()).toBeTruthy();
314
});
315
282
- it('should correctly determine if a null component is mounted', () => {
316
+ it('should correctly determine if a null component is mounted', async () => {
317
class Component extends React.Component {
318
_isMounted() {
319
// No longer a public API, but we can test that it works internally by
@@ -298,12 +332,17 @@ describe('ReactComponentLifeCycle', () => {
332
}
333
}
334
301
- const element = <Component />;
335
+ let instance;
336
+ const element = <Component ref={current => (instance = current)} />;
337
303
- expect(() => {
304
- const instance = ReactTestUtils.renderIntoDocument(element);
305
- expect(instance._isMounted()).toBeTruthy();
338
+ const container = document.createElement('div');
339
+ const root = ReactDOMClient.createRoot(container);
340
+ await expect(async () => {
341
+ await act(() => {
342
+ root.render(element);
343
+ });
344
}).toErrorDev('Component is accessing isMounted inside its render()');
345
+ expect(instance._isMounted()).toBeTruthy();
346
});
347
348
it('isMounted should return false when unmounted', async () => {
@@ -331,7 +370,7 @@ describe('ReactComponentLifeCycle', () => {
370
expect(instance.updater.isMounted(instance)).toBe(false);
371
});
372
334
- it('warns if findDOMNode is used inside render', () => {
373
+ it('warns if legacy findDOMNode is used inside render', async () => {
374
class Component extends React.Component {
375
state = {isMounted: false};
376
componentDidMount() {
@@ -345,8 +384,12 @@ describe('ReactComponentLifeCycle', () => {
384
}
385
}
386
348
- expect(() => {
349
- ReactTestUtils.renderIntoDocument(<Component />);
387
+ const container = document.createElement('div');
388
+ const root = ReactDOMClient.createRoot(container);
389
+ await expect(async () => {
390
+ await act(() => {
391
+ root.render(<Component />);
392
+ });
393
}).toErrorDev('Component is accessing findDOMNode inside its render()');
394
});
395