11
12
let React = require('react');
13
let ReactDOM;
14
+let ReactDOMClient;
15
let ReactDOMServer;
16
let Scheduler;
17
let ReactFeatureFlags;
101
102
React = require('react');
103
ReactDOM = require('react-dom');
104
+ ReactDOMClient = require('react-dom/client');
105
act = require('jest-react').act;
106
ReactDOMServer = require('react-dom/server');
107
Scheduler = require('scheduler');
166
// On the client we don't have all data yet but we want to start
167
// hydrating anyway.
168
suspend = true;
167
- ReactDOM.hydrateRoot(container, <App />);
169
+ ReactDOMClient.hydrateRoot(container, <App />);
170
Scheduler.unstable_flushAll();
171
jest.runAllTimers();
172
219
// On the client we don't have all data yet but we want to start
220
// hydrating anyway.
221
suspend = true;
220
- ReactDOM.hydrateRoot(container, <App />, {
222
+ ReactDOMClient.hydrateRoot(container, <App />, {
223
onRecoverableError(error) {
224
Scheduler.unstable_yieldValue(error.message);
225
},
312
suspend = true;
313
client = true;
314
313
- ReactDOM.hydrateRoot(container, <App />, {
315
+ ReactDOMClient.hydrateRoot(container, <App />, {
316
onRecoverableError(error) {
317
Scheduler.unstable_yieldValue(error.message);
318
},
428
// hydrating anyway.
429
suspend = true;
430
suspend2 = true;
429
- const root = ReactDOM.hydrateRoot(container, <App />, {
431
+ const root = ReactDOMClient.hydrateRoot(container, <App />, {
432
onHydrated(node) {
433
hydrated.push(node);
434
},
485
const container = document.createElement('div');
486
container.innerHTML = finalHTML;
487
486
- ReactDOM.hydrateRoot(container, <App />);
488
+ ReactDOMClient.hydrateRoot(container, <App />);
489
Scheduler.unstable_flushAll();
490
jest.runAllTimers();
491
519
520
expect(() => {
521
act(() => {
520
- ReactDOM.hydrateRoot(container, <App hasB={false} />, {
522
+ ReactDOMClient.hydrateRoot(container, <App hasB={false} />, {
523
onRecoverableError(error) {
524
Scheduler.unstable_yieldValue(error.message);
525
},
592
593
shouldSuspend = true;
594
act(() => {
593
- ReactDOM.hydrateRoot(container, <App hasB={false} />);
595
+ ReactDOMClient.hydrateRoot(container, <App hasB={false} />);
596
});
597
598
resolve();
653
654
expect(() => {
655
act(() => {
654
- ReactDOM.hydrateRoot(container, <App hasB={false} />, {
656
+ ReactDOMClient.hydrateRoot(container, <App hasB={false} />, {
657
onRecoverableError(error) {
658
Scheduler.unstable_yieldValue(error.message);
659
},
711
// On the client we don't have all data yet but we want to start
712
// hydrating anyway.
713
suspend = true;
712
- const root = ReactDOM.hydrateRoot(container, <App />, {
714
+ const root = ReactDOMClient.hydrateRoot(container, <App />, {
715
onDeleted(node) {
716
deleted.push(node);
717
},
772
}).toErrorDev(
773
'Warning: Cannot hydrate Suspense in legacy mode. Switch from ' +
774
'ReactDOM.hydrate(element, container) to ' +
773
- 'ReactDOM.hydrateRoot(container, <App />)' +
775
+ 'ReactDOMClient.hydrateRoot(container, <App />)' +
776
'.render(element) or remove the Suspense components from the server ' +
777
'rendered components.' +
778
'\n in Suspense (at **)' +
852
suspend = true;
853
854
act(() => {
853
- ReactDOM.hydrateRoot(container, <App />);
855
+ ReactDOMClient.hydrateRoot(container, <App />);
856
});
857
858
expect(container.firstChild.firstChild.tagName).not.toBe('DIV');
908
// hydrating anyway.
909
suspend = true;
910
act(() => {
909
- ReactDOM.hydrateRoot(container, <App />);
911
+ ReactDOMClient.hydrateRoot(container, <App />);
912
});
913
914
expect(container.firstChild.children[1].textContent).toBe('Middle');
957
// On the client we don't have all data yet but we want to start
958
// hydrating anyway.
959
suspend = true;
958
- const root = ReactDOM.hydrateRoot(
960
+ const root = ReactDOMClient.hydrateRoot(
961
container,
962
<App text="Hello" className="hello" />,
963
);
1031
// On the client we don't have all data yet but we want to start
1032
// hydrating anyway.
1033
suspend = true;
1032
- const root = ReactDOM.hydrateRoot(
1034
+ const root = ReactDOMClient.hydrateRoot(
1035
container,
1036
<App text="Hello" className="hello" />,
1037
);
1104
// On the client we don't have all data yet but we want to start
1105
// hydrating anyway.
1106
suspend = true;
1105
- const root = ReactDOM.hydrateRoot(
1107
+ const root = ReactDOMClient.hydrateRoot(
1108
container,
1109
<App text="Hello" className="hello" />,
1110
{
1190
// On the client we don't have all data yet but we want to start
1191
// hydrating anyway.
1192
suspend = true;
1191
- const root = ReactDOM.hydrateRoot(
1193
+ const root = ReactDOMClient.hydrateRoot(
1194
container,
1195
<App text="Hello" className="hello" />,
1196
{
1275
// On the client we don't have all data yet but we want to start
1276
// hydrating anyway.
1277
suspend = true;
1276
- const root = ReactDOM.hydrateRoot(
1278
+ const root = ReactDOMClient.hydrateRoot(
1279
container,
1280
<App text="Hello" className="hello" />,
1281
{
1359
// On the client we don't have all data yet but we want to start
1360
// hydrating anyway.
1361
suspend = true;
1360
- const root = ReactDOM.hydrateRoot(
1362
+ const root = ReactDOMClient.hydrateRoot(
1363
container,
1364
<App text="Hello" className="hello" />,
1365
);
1441
const container = document.createElement('div');
1442
container.innerHTML = finalHTML;
1443
1442
- ReactDOM.hydrateRoot(container, <App text="Hello" className="hello" />);
1444
+ ReactDOMClient.hydrateRoot(
1445
+ container,
1446
+ <App text="Hello" className="hello" />,
1447
+ );
1448
1449
await act(async () => {
1450
suspend = true;
1514
// On the client we don't have all data yet but we want to start
1515
// hydrating anyway.
1516
suspend = true;
1512
- const root = ReactDOM.hydrateRoot(
1517
+ const root = ReactDOMClient.hydrateRoot(
1518
container,
1519
<Context.Provider value={{text: 'Hello', className: 'hello'}}>
1520
<App />
1596
// On the client we don't have all data yet but we want to start
1597
// hydrating anyway.
1598
suspend = true;
1594
- const root = ReactDOM.hydrateRoot(
1599
+ const root = ReactDOMClient.hydrateRoot(
1600
container,
1601
<Context.Provider value={{text: 'Hello', className: 'hello'}}>
1602
<App />
1685
1686
// On the client we have the data available quickly for some reason.
1687
suspend = false;
1683
- ReactDOM.hydrateRoot(container, <App />, {
1688
+ ReactDOMClient.hydrateRoot(container, <App />, {
1689
onRecoverableError(error) {
1690
Scheduler.unstable_yieldValue(error.message);
1691
},
1747
1748
// On the client we have the data available quickly for some reason.
1749
suspend = false;
1745
- ReactDOM.hydrateRoot(container, <App />, {
1750
+ ReactDOMClient.hydrateRoot(container, <App />, {
1751
onRecoverableError(error) {
1752
Scheduler.unstable_yieldValue(error.message);
1753
},
1814
1815
// On the client we have the data available quickly for some reason.
1816
suspend = false;
1812
- ReactDOM.hydrateRoot(container, <App />, {
1817
+ ReactDOMClient.hydrateRoot(container, <App />, {
1818
onRecoverableError(error) {
1819
Scheduler.unstable_yieldValue(error.message);
1820
},
1887
1888
const spanB = container.getElementsByTagName('span')[1];
1889
1885
- const root = ReactDOM.hydrateRoot(container, <App showMore={false} />);
1890
+ const root = ReactDOMClient.hydrateRoot(
1891
+ container,
1892
+ <App showMore={false} />,
1893
+ );
1894
suspend = true;
1895
Scheduler.unstable_flushAll();
1896
1970
1971
const spanA = container.getElementsByTagName('span')[0];
1972
1965
- const root = ReactDOM.hydrateRoot(container, <App showMore={false} />);
1973
+ const root = ReactDOMClient.hydrateRoot(
1974
+ container,
1975
+ <App showMore={false} />,
1976
+ );
1977
1978
suspend = true;
1979
Scheduler.unstable_flushAll();
2059
const b = container.getElementsByTagName('span')[1];
2060
expect(b.textContent).toBe('B');
2061
2051
- const root = ReactDOM.hydrateRoot(container, <App />);
2062
+ const root = ReactDOMClient.hydrateRoot(container, <App />);
2063
2064
// Increase hydration priority to higher than "offscreen".
2065
root.unstable_scheduleHydration(b);
2130
const container = document.createElement('div');
2131
container.innerHTML = html;
2132
2122
- ReactDOM.hydrateRoot(container, <App />, {
2133
+ ReactDOMClient.hydrateRoot(container, <App />, {
2134
onRecoverableError(error) {
2135
Scheduler.unstable_yieldValue(error.message);
2136
},
2195
const span = container.getElementsByTagName('span')[1];
2196
2197
suspend = false;
2187
- ReactDOM.hydrateRoot(container, <App />, {
2198
+ ReactDOMClient.hydrateRoot(container, <App />, {
2199
onRecoverableError(error) {
2200
Scheduler.unstable_yieldValue(error.message);
2201
},
2244
2245
// On the client we don't have all data yet but we want to start
2246
// hydrating anyway.
2236
- ReactDOM.hydrateRoot(container, <App />);
2247
+ ReactDOMClient.hydrateRoot(container, <App />);
2248
Scheduler.unstable_flushAll();
2249
jest.runAllTimers();
2250
2296
// On the client we don't have all data yet but we want to start
2297
// hydrating anyway.
2298
suspend = true;
2288
- const root = ReactDOM.hydrateRoot(
2299
+ const root = ReactDOMClient.hydrateRoot(
2300
container,
2301
<ClassName.Provider value={'hello'}>
2302
<App text="Hello" />
2399
// On the client we don't have all data yet but we want to start
2400
// hydrating anyway.
2401
suspend = true;
2391
- ReactDOM.hydrateRoot(container, <App />);
2402
+ ReactDOMClient.hydrateRoot(container, <App />);
2403
Scheduler.unstable_flushAll();
2404
jest.runAllTimers();
2405
2486
// hydrating anyway.
2487
suspend = true;
2488
isServerRendering = false;
2478
- ReactDOM.hydrateRoot(container, <App />);
2489
+ ReactDOMClient.hydrateRoot(container, <App />);
2490
2491
// We'll do one click before hydrating.
2492
a.click();
2576
// On the client we don't have all data yet but we want to start
2577
// hydrating anyway.
2578
suspend = true;
2568
- ReactDOM.hydrateRoot(container, <App />);
2579
+ ReactDOMClient.hydrateRoot(container, <App />);
2580
2581
// We'll do one click before hydrating.
2582
await act(async () => {
2671
// hydrating anyway.
2672
suspend = true;
2673
isServerRendering = false;
2663
- ReactDOM.hydrateRoot(container, <App />);
2674
+ ReactDOMClient.hydrateRoot(container, <App />);
2675
2676
// We'll do one click before hydrating.
2677
a.click();
2758
// On the client we don't have all data yet but we want to start
2759
// hydrating anyway.
2760
suspend = true;
2750
- ReactDOM.hydrateRoot(container, <App />);
2761
+ ReactDOMClient.hydrateRoot(container, <App />);
2762
Scheduler.unstable_flushAll();
2763
jest.runAllTimers();
2764
2833
2834
// We're going to use a different root as a parent.
2835
// This lets us detect whether an event goes through React's event system.
2825
- const parentRoot = ReactDOM.createRoot(parentContainer);
2836
+ const parentRoot = ReactDOMClient.createRoot(parentContainer);
2837
parentRoot.render(<Parent />);
2838
Scheduler.unstable_flushAll();
2839
2846
suspend = true;
2847
2848
// Hydrate asynchronously.
2838
- ReactDOM.hydrateRoot(childContainer, <App />);
2849
+ ReactDOMClient.hydrateRoot(childContainer, <App />);
2850
jest.runAllTimers();
2851
Scheduler.unstable_flushAll();
2852
2944
// hydrating anyway.
2945
suspend1 = true;
2946
suspend2 = true;
2936
- ReactDOM.hydrateRoot(container, <App />);
2947
+ ReactDOMClient.hydrateRoot(container, <App />);
2948
2949
Scheduler.unstable_flushAll();
2950
jest.runAllTimers();
3030
container.innerHTML = finalHTML;
3031
3032
suspend = true;
3022
- const root = ReactDOM.hydrateRoot(container, <App showSibling={false} />);
3033
+ const root = ReactDOMClient.hydrateRoot(
3034
+ container,
3035
+ <App showSibling={false} />,
3036
+ );
3037
expect(Scheduler).toFlushAndYield([]);
3038
3039
expect(ref.current).toBe(null);
3119
// On the client we don't have all data yet but we want to start
3120
// hydrating anyway.
3121
suspend = true;
3108
- ReactDOM.hydrateRoot(container, <App />);
3122
+ ReactDOMClient.hydrateRoot(container, <App />);
3123
Scheduler.unstable_flushAll();
3124
jest.runAllTimers();
3125
3184
const span = container.getElementsByTagName('span')[0];
3185
expect(span.innerHTML).toBe('Hidden child');
3186
3173
- ReactDOM.hydrateRoot(container, <App />, {
3187
+ ReactDOMClient.hydrateRoot(container, <App />, {
3188
onRecoverableError(error) {
3189
Scheduler.unstable_yieldValue(
3190
'Log recoverable error: ' + error.message,
3219
const span = container.getElementsByTagName('span')[0];
3220
expect(span.innerHTML).toBe('Hidden child');
3221
3208
- ReactDOM.hydrateRoot(container, <App />);
3222
+ ReactDOMClient.hydrateRoot(container, <App />);
3223
Scheduler.unstable_flushAll();
3224
expect(ref.current).toBe(span);
3225
expect(span.innerHTML).toBe('Hidden child');
3244
3245
const span = container.getElementsByTagName('span')[0];
3246
3233
- ReactDOM.hydrateRoot(container, <App />);
3247
+ ReactDOMClient.hydrateRoot(container, <App />);
3248
Scheduler.unstable_flushAll();
3249
expect(ref.current).toBe(span);
3250
expect(ref.current.innerHTML).toBe('Hidden child');
3257
const finalHTML = ReactDOMServer.renderToString(<App />);
3258
container.innerHTML = finalHTML;
3259
3246
- ReactDOM.hydrateRoot(container, <App />);
3260
+ ReactDOMClient.hydrateRoot(container, <App />);
3261
Scheduler.unstable_flushAll();
3262
});
3263
}
3335
3336
expect(() => {
3337
act(() => {
3324
- ReactDOM.hydrateRoot(container, <App />, {
3338
+ ReactDOMClient.hydrateRoot(container, <App />, {
3339
onRecoverableError(error) {
3340
Scheduler.unstable_yieldValue(
3341
'Log recoverable error: ' + error.message,
3387
);
3388
expect(() => {
3389
act(() => {
3376
- ReactDOM.hydrateRoot(container, <DirectTextChild text="bad" />, {
3390
+ ReactDOMClient.hydrateRoot(container, <DirectTextChild text="bad" />, {
3391
onRecoverableError(error) {
3392
Scheduler.unstable_yieldValue(error.message);
3393
},
3428
);
3429
expect(() => {
3430
act(() => {
3417
- ReactDOM.hydrateRoot(container2, <TextChildWithSibling text="bad" />, {
3418
- onRecoverableError(error) {
3419
- Scheduler.unstable_yieldValue(error.message);
3431
+ ReactDOMClient.hydrateRoot(
3432
+ container2,
3433
+ <TextChildWithSibling text="bad" />,
3434
+ {
3435
+ onRecoverableError(error) {
3436
+ Scheduler.unstable_yieldValue(error.message);
3437
+ },
3438
},
3421
- });
3439
+ );
3440
});
3441
}).toErrorDev(
3442
[