Update entry point exports (#21488)
The following APIs have been added to the `react` stable entry point: * `SuspenseList` * `startTransition` * `unstable_createMutableSource` * `unstable_useMutableSource` * `useDeferredValue` * `useTransition` The following APIs have been added or removed from the `react-dom` stable entry point: * `createRoot` * `unstable_createPortal` (removed) The following APIs have been added to the `react-is` stable entry point: * `SuspenseList` * `isSuspenseList` The following feature flags have been changed from experimental to true: * `enableLazyElements` * `enableSelectiveHydration` * `enableSuspenseServerRenderer`
Brian Vaughn committed
May 12, 2021 at 11:28 UTC
2bf4805e4bd63dab45cd7f5e1ad32ef8fed3f6ab
92 files changed
+572
-966
packages/create-subscription/src/__tests__/createSubscription-test.js
+2
-4
@@ -268,7 +268,6 @@ describe('createSubscription', () => {
268
expect(Scheduler).toFlushAndYield(['b-1']);
269
});
270
271
- // @gate experimental || !enableSyncDefaultUpdates
271
it('should ignore values emitted by a new subscribable until the commit phase', () => {
272
const log = [];
273
@@ -327,7 +326,7 @@ describe('createSubscription', () => {
326
327
// Start React update, but don't finish
328
if (gate(flags => flags.enableSyncDefaultUpdates)) {
330
- React.unstable_startTransition(() => {
329
+ React.startTransition(() => {
330
ReactNoop.render(<Parent observed={observableB} />);
331
});
332
} else {
@@ -362,7 +361,6 @@ describe('createSubscription', () => {
361
]);
362
});
363
365
- // @gate experimental || !enableSyncDefaultUpdates
364
it('should not drop values emitted between updates', () => {
365
const log = [];
366
@@ -421,7 +419,7 @@ describe('createSubscription', () => {
419
420
// Start React update, but don't finish
421
if (gate(flags => flags.enableSyncDefaultUpdates)) {
424
- React.unstable_startTransition(() => {
422
+ React.startTransition(() => {
423
ReactNoop.render(<Parent observed={observableB} />);
424
});
425
} else {
packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js
+38
-39
@@ -366,10 +366,9 @@ describe('ReactHooksInspectionIntegration', () => {
366
]);
367
});
368
369
- // @gate experimental
369
it('should support composite useTransition hook', () => {
370
function Foo(props) {
372
- React.unstable_useTransition();
371
+ React.useTransition();
372
const memoizedValue = React.useMemo(() => 'hello', []);
373
return <div>{memoizedValue}</div>;
374
}
@@ -394,10 +393,9 @@ describe('ReactHooksInspectionIntegration', () => {
393
]);
394
});
395
397
- // @gate experimental
396
it('should support composite useDeferredValue hook', () => {
397
function Foo(props) {
400
- React.unstable_useDeferredValue('abc', {
398
+ React.useDeferredValue('abc', {
399
timeoutMs: 500,
400
});
401
const [state] = React.useState(() => 'hello', []);
@@ -424,7 +422,6 @@ describe('ReactHooksInspectionIntegration', () => {
422
]);
423
});
424
427
- // @gate experimental
425
it('should support composite useOpaqueIdentifier hook', () => {
426
function Foo(props) {
427
const id = React.unstable_useOpaqueIdentifier();
@@ -452,7 +449,6 @@ describe('ReactHooksInspectionIntegration', () => {
449
});
450
});
451
455
- // @gate experimental
452
it('should support composite useOpaqueIdentifier hook in concurrent mode', () => {
453
function Foo(props) {
454
const id = React.unstable_useOpaqueIdentifier();
@@ -846,37 +842,40 @@ describe('ReactHooksInspectionIntegration', () => {
842
]);
843
});
844
849
- if (__EXPERIMENTAL__) {
850
- it('should support composite useMutableSource hook', () => {
851
- const mutableSource = React.unstable_createMutableSource({}, () => 1);
852
- function Foo(props) {
853
- React.unstable_useMutableSource(
854
- mutableSource,
855
- () => 'snapshot',
856
- () => {},
857
- );
858
- React.useMemo(() => 'memo', []);
859
- return <div />;
860
- }
861
- const renderer = ReactTestRenderer.create(<Foo />);
862
- const childFiber = renderer.root.findByType(Foo)._currentFiber();
863
- const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
864
- expect(tree).toEqual([
865
- {
866
- id: 0,
867
- isStateEditable: false,
868
- name: 'MutableSource',
869
- value: 'snapshot',
870
- subHooks: [],
871
- },
872
- {
873
- id: 1,
874
- isStateEditable: false,
875
- name: 'Memo',
876
- value: 'memo',
877
- subHooks: [],
878
- },
879
- ]);
880
- });
881
- }
845
+ it('should support composite useMutableSource hook', () => {
846
+ const createMutableSource =
847
+ React.createMutableSource || React.unstable_createMutableSource;
848
+ const useMutableSource =
849
+ React.useMutableSource || React.unstable_useMutableSource;
850
+
851
+ const mutableSource = createMutableSource({}, () => 1);
852
+ function Foo(props) {
853
+ useMutableSource(
854
+ mutableSource,
855
+ () => 'snapshot',
856
+ () => {},
857
+ );
858
+ React.useMemo(() => 'memo', []);
859
+ return <div />;
860
+ }
861
+ const renderer = ReactTestRenderer.create(<Foo />);
862
+ const childFiber = renderer.root.findByType(Foo)._currentFiber();
863
+ const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
864
+ expect(tree).toEqual([
865
+ {
866
+ id: 0,
867
+ isStateEditable: false,
868
+ name: 'MutableSource',
869
+ value: 'snapshot',
870
+ subHooks: [],
871
+ },
872
+ {
873
+ id: 1,
874
+ isStateEditable: false,
875
+ name: 'Memo',
876
+ value: 'memo',
877
+ subHooks: [],
878
+ },
879
+ ]);
880
+ });
881
});
packages/react-devtools-core/src/standalone.js
+1
-1
@@ -12,7 +12,7 @@ import {
12
// $FlowFixMe Flow does not yet know about flushSync()
13
flushSync,
14
// $FlowFixMe Flow does not yet know about createRoot()
15
- unstable_createRoot as createRoot,
15
+ createRoot,
16
} from 'react-dom';
17
import Bridge from 'react-devtools-shared/src/bridge';
18
import Store from 'react-devtools-shared/src/devtools/store';
packages/react-devtools-extensions/src/main.js
+1
-1
@@ -1,7 +1,7 @@
1
/* global chrome */
2
3
import {createElement} from 'react';
4
-import {unstable_createRoot as createRoot, flushSync} from 'react-dom';
4
+import {createRoot, flushSync} from 'react-dom';
5
import Bridge from 'react-devtools-shared/src/bridge';
6
import Store from 'react-devtools-shared/src/devtools/store';
7
import {getBrowserName, getBrowserTheme} from './utils';
packages/react-devtools-scheduling-profiler/src/hooks.js
+3
-1
@@ -8,9 +8,11 @@
8
*/
9
10
import {
11
+ // $FlowFixMe
12
unstable_createMutableSource as createMutableSource,
12
- unstable_useMutableSource as useMutableSource,
13
useLayoutEffect,
14
+ // $FlowFixMe
15
+ unstable_useMutableSource as useMutableSource,
16
} from 'react';
17
18
import {
packages/react-devtools-scheduling-profiler/src/import-worker/__tests__/preprocessData-test.internal.js
+1
-1
@@ -382,7 +382,7 @@ describe(preprocessData, () => {
382
});
383
});
384
385
- // @gate experimental && enableSchedulingProfiler
385
+ // @gate enableSchedulingProfiler
386
it('should process a sample createRoot render sequence', () => {
387
function App() {
388
const [didMount, setDidMount] = React.useState(false);
packages/react-devtools-scheduling-profiler/src/index.js
+1
-1
@@ -11,7 +11,7 @@ import 'regenerator-runtime/runtime';
11
12
import * as React from 'react';
13
// $FlowFixMe Flow does not yet know about createRoot()
14
-import {unstable_createRoot as createRoot} from 'react-dom';
14
+import {createRoot} from 'react-dom';
15
import nullthrows from 'nullthrows';
16
import App from './App';
17
packages/react-devtools-shared/src/__tests__/profilingCommitTreeBuilder-test.js
+2
-2
@@ -149,7 +149,7 @@ describe('commit tree', () => {
149
150
it('should support Lazy components (createRoot)', async () => {
151
const container = document.createElement('div');
152
- const root = ReactDOM.unstable_createRoot(container);
152
+ const root = ReactDOM.createRoot(container);
153
154
utils.act(() => store.profilerStore.startProfiling());
155
utils.act(() => root.render(<App renderChildren={true} />));
@@ -226,7 +226,7 @@ describe('commit tree', () => {
226
227
it('should support Lazy components that are unmounted before resolving (createRoot)', async () => {
228
const container = document.createElement('div');
229
- const root = ReactDOM.unstable_createRoot(container);
229
+ const root = ReactDOM.createRoot(container);
230
231
utils.act(() => store.profilerStore.startProfiling());
232
utils.act(() => root.render(<App renderChildren={true} />));
packages/react-devtools-shared/src/__tests__/profilingHostRoot-test.js
+2
-2
@@ -89,7 +89,7 @@ describe('profiling HostRoot', () => {
89
utils.act(() => store.profilerStore.startProfiling());
90
utils.act(() => {
91
const container = document.createElement('div');
92
- const root = ReactDOM.unstable_createRoot(container);
92
+ const root = ReactDOM.createRoot(container);
93
root.render(<App />);
94
});
95
utils.act(() => store.profilerStore.stopProfiling());
@@ -122,7 +122,7 @@ describe('profiling HostRoot', () => {
122
}
123
124
const container = document.createElement('div');
125
- const root = ReactDOM.unstable_createRoot(container);
125
+ const root = ReactDOM.createRoot(container);
126
127
utils.act(() => store.profilerStore.startProfiling());
128
utils.act(() => root.render(<App />));
packages/react-devtools-shared/src/__tests__/store-test.js
+5
-5
@@ -356,18 +356,18 @@ describe('Store', () => {
356
};
357
const Wrapper = ({shouldSuspense}) => (
358
<React.Fragment>
359
- <React.unstable_SuspenseList revealOrder="forwards" tail="collapsed">
359
+ <React.SuspenseList revealOrder="forwards" tail="collapsed">
360
<Component key="A" />
361
<React.Suspense fallback={<Loading />}>
362
{shouldSuspense ? <SuspendingComponent /> : <Component key="B" />}
363
</React.Suspense>
364
<Component key="C" />
365
- </React.unstable_SuspenseList>
365
+ </React.SuspenseList>
366
</React.Fragment>
367
);
368
369
const container = document.createElement('div');
370
- const root = ReactDOM.unstable_createRoot(container);
370
+ const root = ReactDOM.createRoot(container);
371
act(() => {
372
root.render(<Wrapper shouldSuspense={true} />);
373
});
@@ -984,7 +984,7 @@ describe('Store', () => {
984
985
it('should support Lazy components in (createRoot)', async () => {
986
const container = document.createElement('div');
987
- const root = ReactDOM.unstable_createRoot(container);
987
+ const root = ReactDOM.createRoot(container);
988
989
// Render once to start fetching the lazy component
990
act(() => root.render(<App renderChildren={true} />));
@@ -1020,7 +1020,7 @@ describe('Store', () => {
1020
1021
it('should support Lazy components that are unmounted before they finish loading in (createRoot)', async () => {
1022
const container = document.createElement('div');
1023
- const root = ReactDOM.unstable_createRoot(container);
1023
+ const root = ReactDOM.createRoot(container);
1024
1025
// Render once to start fetching the lazy component
1026
act(() => root.render(<App renderChildren={true} />));
packages/react-devtools-shared/src/__tests__/storeStressTestConcurrent-test.js
+18
-18
@@ -67,7 +67,7 @@ describe('StoreStressConcurrent', () => {
67
// 1. Render a normal version of [a, b, c, d, e].
68
let container = document.createElement('div');
69
// $FlowFixMe
70
- let root = ReactDOM.unstable_createRoot(container);
70
+ let root = ReactDOM.createRoot(container);
71
act(() => root.render(<Parent>{[a, b, c, d, e]}</Parent>));
72
expect(store).toMatchInlineSnapshot(
73
`
@@ -151,7 +151,7 @@ describe('StoreStressConcurrent', () => {
151
// Ensure fresh mount.
152
container = document.createElement('div');
153
// $FlowFixMe
154
- root = ReactDOM.unstable_createRoot(container);
154
+ root = ReactDOM.createRoot(container);
155
156
// Verify mounting 'abcde'.
157
act(() => root.render(<Parent>{cases[i]}</Parent>));
@@ -181,7 +181,7 @@ describe('StoreStressConcurrent', () => {
181
// There'll be no unmounting until the very end.
182
container = document.createElement('div');
183
// $FlowFixMe
184
- root = ReactDOM.unstable_createRoot(container);
184
+ root = ReactDOM.createRoot(container);
185
for (let i = 0; i < cases.length; i++) {
186
// Verify mounting 'abcde'.
187
act(() => root.render(<Parent>{cases[i]}</Parent>));
@@ -247,7 +247,7 @@ describe('StoreStressConcurrent', () => {
247
const snapshots = [];
248
let container = document.createElement('div');
249
// $FlowFixMe
250
- let root = ReactDOM.unstable_createRoot(container);
250
+ let root = ReactDOM.createRoot(container);
251
for (let i = 0; i < steps.length; i++) {
252
act(() => root.render(<Root>{steps[i]}</Root>));
253
// We snapshot each step once so it doesn't regress.
@@ -320,7 +320,7 @@ describe('StoreStressConcurrent', () => {
320
for (let j = 0; j < steps.length; j++) {
321
container = document.createElement('div');
322
// $FlowFixMe
323
- root = ReactDOM.unstable_createRoot(container);
323
+ root = ReactDOM.createRoot(container);
324
act(() => root.render(<Root>{steps[i]}</Root>));
325
expect(print(store)).toMatch(snapshots[i]);
326
act(() => root.render(<Root>{steps[j]}</Root>));
@@ -337,7 +337,7 @@ describe('StoreStressConcurrent', () => {
337
for (let j = 0; j < steps.length; j++) {
338
container = document.createElement('div');
339
// $FlowFixMe
340
- root = ReactDOM.unstable_createRoot(container);
340
+ root = ReactDOM.createRoot(container);
341
act(() =>
342
root.render(
343
<Root>
@@ -409,7 +409,7 @@ describe('StoreStressConcurrent', () => {
409
const snapshots = [];
410
let container = document.createElement('div');
411
// $FlowFixMe
412
- let root = ReactDOM.unstable_createRoot(container);
412
+ let root = ReactDOM.createRoot(container);
413
for (let i = 0; i < steps.length; i++) {
414
act(() =>
415
root.render(
@@ -536,7 +536,7 @@ describe('StoreStressConcurrent', () => {
536
// Always start with a fresh container and steps[i].
537
container = document.createElement('div');
538
// $FlowFixMe
539
- root = ReactDOM.unstable_createRoot(container);
539
+ root = ReactDOM.createRoot(container);
540
act(() =>
541
root.render(
542
<Root>
@@ -582,7 +582,7 @@ describe('StoreStressConcurrent', () => {
582
// Always start with a fresh container and steps[i].
583
container = document.createElement('div');
584
// $FlowFixMe
585
- root = ReactDOM.unstable_createRoot(container);
585
+ root = ReactDOM.createRoot(container);
586
act(() =>
587
root.render(
588
<Root>
@@ -640,7 +640,7 @@ describe('StoreStressConcurrent', () => {
640
// Always start with a fresh container and steps[i].
641
container = document.createElement('div');
642
// $FlowFixMe
643
- root = ReactDOM.unstable_createRoot(container);
643
+ root = ReactDOM.createRoot(container);
644
act(() =>
645
root.render(
646
<Root>
@@ -690,7 +690,7 @@ describe('StoreStressConcurrent', () => {
690
// Always start with a fresh container and steps[i].
691
container = document.createElement('div');
692
// $FlowFixMe
693
- root = ReactDOM.unstable_createRoot(container);
693
+ root = ReactDOM.createRoot(container);
694
act(() =>
695
root.render(
696
<Root>
@@ -744,7 +744,7 @@ describe('StoreStressConcurrent', () => {
744
// Always start with a fresh container and steps[i].
745
container = document.createElement('div');
746
// $FlowFixMe
747
- root = ReactDOM.unstable_createRoot(container);
747
+ root = ReactDOM.createRoot(container);
748
act(() =>
749
root.render(
750
<Root>
@@ -898,7 +898,7 @@ describe('StoreStressConcurrent', () => {
898
const snapshots = [];
899
let container = document.createElement('div');
900
// $FlowFixMe
901
- let root = ReactDOM.unstable_createRoot(container);
901
+ let root = ReactDOM.createRoot(container);
902
for (let i = 0; i < steps.length; i++) {
903
act(() =>
904
root.render(
@@ -1055,7 +1055,7 @@ describe('StoreStressConcurrent', () => {
1055
// Always start with a fresh container and steps[i].
1056
container = document.createElement('div');
1057
// $FlowFixMe
1058
- root = ReactDOM.unstable_createRoot(container);
1058
+ root = ReactDOM.createRoot(container);
1059
act(() =>
1060
root.render(
1061
<Root>
@@ -1107,7 +1107,7 @@ describe('StoreStressConcurrent', () => {
1107
// Always start with a fresh container and steps[i].
1108
container = document.createElement('div');
1109
// $FlowFixMe
1110
- root = ReactDOM.unstable_createRoot(container);
1110
+ root = ReactDOM.createRoot(container);
1111
act(() =>
1112
root.render(
1113
<Root>
@@ -1174,7 +1174,7 @@ describe('StoreStressConcurrent', () => {
1174
// Always start with a fresh container and steps[i].
1175
container = document.createElement('div');
1176
// $FlowFixMe
1177
- root = ReactDOM.unstable_createRoot(container);
1177
+ root = ReactDOM.createRoot(container);
1178
act(() =>
1179
root.render(
1180
<Root>
@@ -1226,7 +1226,7 @@ describe('StoreStressConcurrent', () => {
1226
// Always start with a fresh container and steps[i].
1227
container = document.createElement('div');
1228
// $FlowFixMe
1229
- root = ReactDOM.unstable_createRoot(container);
1229
+ root = ReactDOM.createRoot(container);
1230
act(() =>
1231
root.render(
1232
<Root>
@@ -1278,7 +1278,7 @@ describe('StoreStressConcurrent', () => {
1278
// Always start with a fresh container and steps[i].
1279
container = document.createElement('div');
1280
// $FlowFixMe
1281
- root = ReactDOM.unstable_createRoot(container);
1281
+ root = ReactDOM.createRoot(container);
1282
act(() =>
1283
root.render(
1284
<Root>
packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContext.js
+1
-1
@@ -10,7 +10,7 @@
10
import * as React from 'react';
11
import {
12
createContext,
13
- unstable_startTransition as startTransition,
13
+ startTransition,
14
unstable_useCacheRefresh as useCacheRefresh,
15
useCallback,
16
useContext,
packages/react-devtools-shared/src/devtools/views/Components/InspectedElementErrorsAndWarningsTree.js
+1
-1
@@ -11,7 +11,7 @@ import * as React from 'react';
11
import {
12
useContext,
13
unstable_useCacheRefresh as useCacheRefresh,
14
- unstable_useTransition as useTransition,
14
+ useTransition,
15
} from 'react';
16
import Button from '../Button';
17
import ButtonIcon from '../ButtonIcon';
packages/react-devtools-shared/src/devtools/views/Components/KeyValue.js
+1
-6
@@ -8,12 +8,7 @@
8
*/
9
10
import * as React from 'react';
11
-import {
12
- unstable_useTransition as useTransition,
13
- useContext,
14
- useRef,
15
- useState,
16
-} from 'react';
11
+import {useTransition, useContext, useRef, useState} from 'react';
12
import EditableName from './EditableName';
13
import EditableValue from './EditableValue';
14
import NewArrayValue from './NewArrayValue';
packages/react-devtools-shared/src/devtools/views/Components/TreeContext.js
+1
-1
@@ -34,7 +34,7 @@ import {
34
useMemo,
35
useReducer,
36
useRef,
37
- unstable_startTransition as startTransition,
37
+ startTransition,
38
} from 'react';
39
import {createRegExp} from '../utils';
40
import {BridgeContext, StoreContext} from '../context';
packages/react-devtools-shared/src/devtools/views/ErrorBoundary/cache.js
+2
-2
@@ -10,7 +10,7 @@
10
import type {Wakeable} from 'shared/ReactTypes';
11
import type {GitHubIssue} from './githubAPI';
12
13
-import {unstable_getCacheForType} from 'react';
13
+import {unstable_getCacheForType as getCacheForType} from 'react';
14
import {searchGitHubIssues} from './githubAPI';
15
16
const API_TIMEOUT = 3000;
@@ -55,7 +55,7 @@ function createMap(): GitHubIssueMap {
55
}
56
57
function getRecordMap(): Map<string, Record<GitHubIssue>> {
58
- return unstable_getCacheForType(createMap);
58
+ return getCacheForType(createMap);
59
}
60
61
export function findGitHubIssue(errorMessage: string): GitHubIssue | null {
packages/react-devtools-shared/src/inspectedElementCache.js
+3
-3
@@ -8,8 +8,8 @@
8
*/
9
10
import {
11
- unstable_getCacheForType,
12
- unstable_startTransition as startTransition,
11
+ unstable_getCacheForType as getCacheForType,
12
+ startTransition,
13
} from 'react';
14
import Store from './devtools/store';
15
import {inspectElement as inspectElementMutableSource} from './inspectedElementMutableSource';
@@ -60,7 +60,7 @@ function createMap(): InspectedElementMap {
60
}
61
62
function getRecordMap(): WeakMap<Element, Record<InspectedElementFrontend>> {
63
- return unstable_getCacheForType(createMap);
63
+ return getCacheForType(createMap);
64
}
65
66
function createCacheSeed(
packages/react-devtools-shell/src/app/SuspenseTree/index.js
+1
-6
@@ -8,12 +8,7 @@
8
*/
9
10
import * as React from 'react';
11
-import {
12
- Fragment,
13
- Suspense,
14
- unstable_SuspenseList as SuspenseList,
15
- useState,
16
-} from 'react';
11
+import {Fragment, Suspense, SuspenseList, useState} from 'react';
12
13
function SuspenseTree() {
14
return (
packages/react-devtools-shell/src/app/index.js
+1
-1
@@ -5,7 +5,7 @@
5
import {createElement} from 'react';
6
import {
7
// $FlowFixMe Flow does not yet know about createRoot()
8
- unstable_createRoot as createRoot,
8
+ createRoot,
9
} from 'react-dom';
10
import DeeplyNestedComponents from './DeeplyNestedComponents';
11
import Iframe from './Iframe';
packages/react-devtools-shell/src/devtools.js
+1
-1
@@ -2,7 +2,7 @@
2
3
import {createElement} from 'react';
4
// $FlowFixMe Flow does not yet know about createRoot()
5
-import {unstable_createRoot as createRoot} from 'react-dom';
5
+import {createRoot} from 'react-dom';
6
import {
7
activate as activateBackend,
8
initialize as initializeBackend,
packages/react-dom/index.classic.fb.js
+10
-11
@@ -19,22 +19,21 @@ Object.assign((__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: any), {
19
});
20
21
export {
22
- createPortal,
23
- unstable_batchedUpdates,
24
- flushSync,
22
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
26
- version,
23
+ createPortal,
24
+ createRoot,
25
+ createRoot as unstable_createRoot, // TODO Remove once callsites use createRoot
26
findDOMNode,
27
+ flushSync,
28
hydrate,
29
render,
30
unmountComponentAtNode,
31
- createRoot,
32
- createRoot as unstable_createRoot,
33
- unstable_flushControlled,
34
- unstable_scheduleHydration,
35
- unstable_runWithPriority,
36
- unstable_renderSubtreeIntoContainer,
37
- unstable_createPortal,
31
+ unstable_batchedUpdates,
32
unstable_createEventHandle,
33
+ unstable_flushControlled,
34
unstable_isNewReconciler,
35
+ unstable_renderSubtreeIntoContainer,
36
+ unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority.
37
+ unstable_scheduleHydration,
38
+ version,
39
} from './src/client/ReactDOM';
packages/react-dom/index.experimental.js
+7
-15
@@ -8,26 +8,18 @@
8
*/
9
10
export {
11
- createPortal,
12
- unstable_batchedUpdates,
13
- flushSync,
11
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
15
- version,
16
- // Disabled behind disableLegacyReactDOMAPIs
12
+ createPortal,
13
+ createRoot,
14
findDOMNode,
15
+ flushSync,
16
hydrate,
17
render,
18
unmountComponentAtNode,
21
- // exposeConcurrentModeAPIs
22
- createRoot as unstable_createRoot,
19
+ unstable_batchedUpdates,
20
unstable_flushControlled,
24
- unstable_scheduleHydration,
25
- // DO NOT USE: Temporarily exposing this to migrate off of Scheduler.runWithPriority.
26
- unstable_runWithPriority,
27
- // Disabled behind disableUnstableRenderSubtreeIntoContainer
21
unstable_renderSubtreeIntoContainer,
29
- // Disabled behind disableUnstableCreatePortal
30
- // Temporary alias since we already shipped React 16 RC with it.
31
- // TODO: remove in React 18.
32
- unstable_createPortal,
22
+ unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority.
23
+ unstable_scheduleHydration,
24
+ version,
25
} from './src/client/ReactDOM';
packages/react-dom/index.js
+10
-11
@@ -10,22 +10,21 @@
10
// Export all exports so that they're available in tests.
11
// We can't use export * from in Flow for some reason.
12
export {
13
- createPortal,
14
- unstable_batchedUpdates,
15
- flushSync,
13
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
17
- version,
14
+ createPortal,
15
+ createRoot,
16
+ createRoot as unstable_createRoot,
17
findDOMNode,
18
+ flushSync,
19
hydrate,
20
render,
21
unmountComponentAtNode,
22
- createRoot,
23
- createRoot as unstable_createRoot,
24
- unstable_flushControlled,
25
- unstable_scheduleHydration,
26
- unstable_runWithPriority,
27
- unstable_renderSubtreeIntoContainer,
28
- unstable_createPortal,
22
+ unstable_batchedUpdates,
23
unstable_createEventHandle,
24
+ unstable_flushControlled,
25
unstable_isNewReconciler,
26
+ unstable_renderSubtreeIntoContainer,
27
+ unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority.
28
+ unstable_scheduleHydration,
29
+ version,
30
} from './src/client/ReactDOM';
packages/react-dom/index.modern.fb.js
+8
-8
@@ -8,16 +8,16 @@
8
*/
9
10
export {
11
- createPortal,
12
- unstable_batchedUpdates,
13
- flushSync,
11
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
15
- version,
12
+ createPortal,
13
createRoot,
17
- createRoot as unstable_createRoot,
18
- unstable_flushControlled,
19
- unstable_scheduleHydration,
20
- unstable_runWithPriority,
14
+ createRoot as unstable_createRoot, // TODO Remove once callsites use createRoot
15
+ flushSync,
16
+ unstable_batchedUpdates,
17
unstable_createEventHandle,
18
+ unstable_flushControlled,
19
unstable_isNewReconciler,
20
+ unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority.
21
+ unstable_scheduleHydration,
22
+ version,
23
} from './src/client/ReactDOM';
packages/react-dom/index.stable.js
+5
-7
@@ -8,17 +8,15 @@
8
*/
9
10
export {
11
- createPortal,
12
- unstable_batchedUpdates,
13
- flushSync,
11
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
15
- version,
12
+ createPortal,
13
+ createRoot,
14
findDOMNode,
15
+ flushSync,
16
hydrate,
17
render,
18
unmountComponentAtNode,
19
+ unstable_batchedUpdates,
20
unstable_renderSubtreeIntoContainer,
21
- // Temporary alias since we already shipped React 16 RC with it.
22
- // TODO: remove in React 18.
23
- unstable_createPortal,
21
+ version,
22
} from './src/client/ReactDOM';
packages/react-dom/src/__tests__/ReactDOMFiber-test.js
-28
@@ -246,34 +246,6 @@ describe('ReactDOMFiber', () => {
246
expect(container.innerHTML).toBe('');
247
});
248
249
- // TODO: remove in React 18
250
- if (!__EXPERIMENTAL__) {
251
- it('should support unstable_createPortal alias', () => {
252
- const portalContainer = document.createElement('div');
253
-
254
- expect(() =>
255
- ReactDOM.render(
256
- <div>
257
- {ReactDOM.unstable_createPortal(<div>portal</div>, portalContainer)}
258
- </div>,
259
- container,
260
- ),
261
- ).toWarnDev(
262
- 'The ReactDOM.unstable_createPortal() alias has been deprecated, ' +
263
- 'and will be removed in React 18+. Update your code to use ' +
264
- 'ReactDOM.createPortal() instead. It has the exact same API, ' +
265
- 'but without the "unstable_" prefix.',
266
- {withoutStack: true},
267
- );
268
- expect(portalContainer.innerHTML).toBe('<div>portal</div>');
269
- expect(container.innerHTML).toBe('<div></div>');
270
-
271
- ReactDOM.unmountComponentAtNode(container);
272
- expect(portalContainer.innerHTML).toBe('');
273
- expect(container.innerHTML).toBe('');
274
- });
275
- }
276
-
249
it('should render many portals', () => {
250
const portalContainer1 = document.createElement('div');
251
const portalContainer2 = document.createElement('div');
packages/react-dom/src/__tests__/ReactDOMFiberAsync-test.js
+11
-20
@@ -148,7 +148,6 @@ describe('ReactDOMFiberAsync', () => {
148
});
149
150
describe('concurrent mode', () => {
151
- // @gate experimental
151
it('does not perform deferred updates synchronously', () => {
152
const inputRef = React.createRef();
153
const asyncValueRef = React.createRef();
@@ -185,7 +184,7 @@ describe('ReactDOMFiberAsync', () => {
184
);
185
}
186
}
188
- const root = ReactDOM.unstable_createRoot(container);
187
+ const root = ReactDOM.createRoot(container);
188
root.render(<Counter />);
189
Scheduler.unstable_flushAll();
190
expect(asyncValueRef.current.textContent).toBe('');
@@ -204,9 +203,8 @@ describe('ReactDOMFiberAsync', () => {
203
expect(syncValueRef.current.textContent).toBe('hello');
204
});
205
207
- // @gate experimental
206
it('top-level updates are concurrent', () => {
209
- const root = ReactDOM.unstable_createRoot(container);
207
+ const root = ReactDOM.createRoot(container);
208
root.render(<div>Hi</div>);
209
expect(container.textContent).toEqual('');
210
Scheduler.unstable_flushAll();
@@ -218,7 +216,6 @@ describe('ReactDOMFiberAsync', () => {
216
expect(container.textContent).toEqual('Bye');
217
});
218
221
- // @gate experimental
219
it('deep updates (setState) are concurrent', () => {
220
let instance;
221
class Component extends React.Component {
@@ -229,7 +226,7 @@ describe('ReactDOMFiberAsync', () => {
226
}
227
}
228
232
- const root = ReactDOM.unstable_createRoot(container);
229
+ const root = ReactDOM.createRoot(container);
230
root.render(<Component />);
231
expect(container.textContent).toEqual('');
232
Scheduler.unstable_flushAll();
@@ -241,7 +238,6 @@ describe('ReactDOMFiberAsync', () => {
238
expect(container.textContent).toEqual('1');
239
});
240
244
- // @gate experimental
241
it('flushSync flushes updates before end of the tick', () => {
242
const ops = [];
243
let instance;
@@ -260,7 +256,7 @@ describe('ReactDOMFiberAsync', () => {
256
}
257
}
258
263
- const root = ReactDOM.unstable_createRoot(container);
259
+ const root = ReactDOM.createRoot(container);
260
root.render(<Component />);
261
Scheduler.unstable_flushAll();
262
@@ -302,7 +298,7 @@ describe('ReactDOMFiberAsync', () => {
298
return this.state.counter;
299
}
300
}
305
- const root = ReactDOM.unstable_createRoot(container);
301
+ const root = ReactDOM.createRoot(container);
302
root.render(<Counter />);
303
Scheduler.unstable_flushAll();
304
expect(container.textContent).toEqual('0');
@@ -385,7 +381,6 @@ describe('ReactDOMFiberAsync', () => {
381
expect(returnValue).toBe(undefined);
382
});
383
388
- // @gate experimental
384
it('ignores discrete events on a pending removed element', async () => {
385
const disableButtonRef = React.createRef();
386
const submitButtonRef = React.createRef();
@@ -406,7 +401,7 @@ describe('ReactDOMFiberAsync', () => {
401
);
402
}
403
409
- const root = ReactDOM.unstable_createRoot(container);
404
+ const root = ReactDOM.createRoot(container);
405
await act(async () => {
406
root.render(<Form />);
407
});
@@ -426,7 +421,6 @@ describe('ReactDOMFiberAsync', () => {
421
expect(submitButton.current).toBe(undefined);
422
});
423
429
- // @gate experimental
424
it('ignores discrete events on a pending removed event listener', async () => {
425
const disableButtonRef = React.createRef();
426
const submitButtonRef = React.createRef();
@@ -458,7 +452,7 @@ describe('ReactDOMFiberAsync', () => {
452
);
453
}
454
461
- const root = ReactDOM.unstable_createRoot(container);
455
+ const root = ReactDOM.createRoot(container);
456
await act(async () => {
457
root.render(<Form />);
458
});
@@ -491,7 +485,6 @@ describe('ReactDOMFiberAsync', () => {
485
expect(formSubmitted).toBe(false);
486
});
487
494
- // @gate experimental
488
it('uses the newest discrete events on a pending changed event listener', async () => {
489
const enableButtonRef = React.createRef();
490
const submitButtonRef = React.createRef();
@@ -518,7 +511,7 @@ describe('ReactDOMFiberAsync', () => {
511
);
512
}
513
521
- const root = ReactDOM.unstable_createRoot(container);
514
+ const root = ReactDOM.createRoot(container);
515
await act(async () => {
516
root.render(<Form />);
517
});
@@ -582,9 +575,8 @@ describe('ReactDOMFiberAsync', () => {
575
expect(containerC.textContent).toEqual('Finished');
576
});
577
585
- // @gate experimental
578
it('updates flush without yielding in the next event', () => {
587
- const root = ReactDOM.unstable_createRoot(container);
579
+ const root = ReactDOM.createRoot(container);
580
581
function Text(props) {
582
Scheduler.unstable_yieldValue(props.text);
@@ -607,7 +599,6 @@ describe('ReactDOMFiberAsync', () => {
599
expect(container.textContent).toEqual('ABC');
600
});
601
610
- // @gate experimental
602
it('unmounted roots should never clear newer root content from a container', () => {
603
const ref = React.createRef();
604
@@ -630,7 +621,7 @@ describe('ReactDOMFiberAsync', () => {
621
return <button ref={ref}>new</button>;
622
}
623
633
- const oldRoot = ReactDOM.unstable_createRoot(container);
624
+ const oldRoot = ReactDOM.createRoot(container);
625
act(() => {
626
oldRoot.render(<OldApp />);
627
});
@@ -642,7 +633,7 @@ describe('ReactDOMFiberAsync', () => {
633
expect(container.textContent).toBe('');
634
635
// We can now render a new one.
645
- const newRoot = ReactDOM.unstable_createRoot(container);
636
+ const newRoot = ReactDOM.createRoot(container);
637
ReactDOM.flushSync(() => {
638
newRoot.render(<NewApp />);
639
});
packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
+8
-8
@@ -38,7 +38,7 @@ describe('ReactDOMFizzServer', () => {
38
}
39
Stream = require('stream');
40
Suspense = React.Suspense;
41
- SuspenseList = React.unstable_SuspenseList;
41
+ SuspenseList = React.SuspenseList;
42
PropTypes = require('prop-types');
43
44
textCache = new Map();
@@ -313,7 +313,7 @@ describe('ReactDOMFizzServer', () => {
313
expect(loggedErrors).toEqual([]);
314
315
// Attempt to hydrate the content.
316
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
316
+ const root = ReactDOM.createRoot(container, {hydrate: true});
317
root.render(<App isClient={true} />);
318
Scheduler.unstable_flushAll();
319
@@ -405,7 +405,7 @@ describe('ReactDOMFizzServer', () => {
405
expect(loggedErrors).toEqual([]);
406
407
// Attempt to hydrate the content.
408
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
408
+ const root = ReactDOM.createRoot(container, {hydrate: true});
409
root.render(<App isClient={true} />);
410
Scheduler.unstable_flushAll();
411
@@ -481,7 +481,7 @@ describe('ReactDOMFizzServer', () => {
481
expect(getVisibleChildren(container)).toEqual(<div>Loading...</div>);
482
483
// Attempt to hydrate the content.
484
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
484
+ const root = ReactDOM.createRoot(container, {hydrate: true});
485
root.render(<App />);
486
Scheduler.unstable_flushAll();
487
@@ -563,7 +563,7 @@ describe('ReactDOMFizzServer', () => {
563
expect(loggedErrors).toEqual([]);
564
565
// Attempt to hydrate the content.
566
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
566
+ const root = ReactDOM.createRoot(container, {hydrate: true});
567
root.render(<App />);
568
Scheduler.unstable_flushAll();
569
@@ -635,7 +635,7 @@ describe('ReactDOMFizzServer', () => {
635
startWriting();
636
});
637
638
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
638
+ const root = ReactDOM.createRoot(container, {hydrate: true});
639
root.render(<App showMore={false} />);
640
Scheduler.unstable_flushAll();
641
@@ -703,7 +703,7 @@ describe('ReactDOMFizzServer', () => {
703
// We're still showing a fallback.
704
705
// Attempt to hydrate the content.
706
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
706
+ const root = ReactDOM.createRoot(container, {hydrate: true});
707
root.render(<App />);
708
Scheduler.unstable_flushAll();
709
@@ -1294,7 +1294,7 @@ describe('ReactDOMFizzServer', () => {
1294
// We're still showing a fallback.
1295
1296
// Attempt to hydrate the content.
1297
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
1297
+ const root = ReactDOM.createRoot(container, {hydrate: true});
1298
root.render(<App isClient={true} />);
1299
Scheduler.unstable_flushAll();
1300
packages/react-dom/src/__tests__/ReactDOMHooks-test.js
+1
-2
@@ -107,7 +107,6 @@ describe('ReactDOMHooks', () => {
107
expect(labelRef.current.innerHTML).toBe('abc');
108
});
109
110
- // @gate experimental
110
it('should not bail out when an update is scheduled from within an event handler in Concurrent Mode', async () => {
111
const {createRef, useCallback, useState} = React;
112
@@ -128,7 +127,7 @@ describe('ReactDOMHooks', () => {
127
const inputRef = createRef();
128
const labelRef = createRef();
129
131
- const root = ReactDOM.unstable_createRoot(container);
130
+ const root = ReactDOM.createRoot(container);
131
root.render(<Example inputRef={inputRef} labelRef={labelRef} />);
132
133
Scheduler.unstable_flushAll();
packages/react-dom/src/__tests__/ReactDOMNativeEventHeuristic-test.js
+8
-16
@@ -42,7 +42,6 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
42
}
43
}
44
45
- // @gate experimental
45
it('ignores discrete events on a pending removed element', async () => {
46
const disableButtonRef = React.createRef();
47
const submitButtonRef = React.createRef();
@@ -66,7 +65,7 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
65
);
66
}
67
69
- const root = ReactDOM.unstable_createRoot(container);
68
+ const root = ReactDOM.createRoot(container);
69
await act(() => {
70
root.render(<Form />);
71
});
@@ -88,7 +87,6 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
87
// We'll assume that the browser won't let the user click it.
88
});
89
91
- // @gate experimental
90
it('ignores discrete events on a pending removed event listener', async () => {
91
const disableButtonRef = React.createRef();
92
const submitButtonRef = React.createRef();
@@ -125,7 +123,7 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
123
);
124
}
125
128
- const root = ReactDOM.unstable_createRoot(container);
126
+ const root = ReactDOM.createRoot(container);
127
root.render(<Form />);
128
// Flush
129
Scheduler.unstable_flushAll();
@@ -157,7 +155,6 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
155
expect(formSubmitted).toBe(false);
156
});
157
160
- // @gate experimental
158
it('uses the newest discrete events on a pending changed event listener', async () => {
159
const enableButtonRef = React.createRef();
160
const submitButtonRef = React.createRef();
@@ -188,7 +185,7 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
185
);
186
}
187
191
- const root = ReactDOM.unstable_createRoot(container);
188
+ const root = ReactDOM.createRoot(container);
189
root.render(<Form />);
190
// Flush
191
Scheduler.unstable_flushAll();
@@ -220,9 +217,8 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
217
expect(formSubmitted).toBe(true);
218
});
219
223
- // @gate experimental
220
it('mouse over should be user-blocking but not discrete', async () => {
225
- const root = ReactDOM.unstable_createRoot(container);
221
+ const root = ReactDOM.createRoot(container);
222
223
const target = React.createRef(null);
224
function Foo() {
@@ -251,9 +247,8 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
247
expect(container.textContent).toEqual('hovered');
248
});
249
254
- // @gate experimental
250
it('mouse enter should be user-blocking but not discrete', async () => {
256
- const root = ReactDOM.unstable_createRoot(container);
251
+ const root = ReactDOM.createRoot(container);
252
253
const target = React.createRef(null);
254
function Foo() {
@@ -284,9 +279,8 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
279
expect(container.textContent).toEqual('hovered');
280
});
281
287
- // @gate experimental
282
it('continuous native events flush as expected', async () => {
289
- const root = ReactDOM.unstable_createRoot(container);
283
+ const root = ReactDOM.createRoot(container);
284
285
const target = React.createRef(null);
286
function Foo({hovered}) {
@@ -324,9 +318,8 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
318
expect(container.textContent).toEqual('hovered');
319
});
320
327
- // @gate experimental
321
it('should batch inside native events', async () => {
329
- const root = ReactDOM.unstable_createRoot(container);
322
+ const root = ReactDOM.createRoot(container);
323
324
const target = React.createRef(null);
325
function Foo() {
@@ -375,9 +368,8 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
368
}
369
});
370
378
- // @gate experimental
371
it('should not flush discrete events at the end of outermost batchedUpdates', async () => {
380
- const root = ReactDOM.unstable_createRoot(container);
372
+ const root = ReactDOM.createRoot(container);
373
374
let target;
375
function Foo() {
packages/react-dom/src/__tests__/ReactDOMNestedEvents-test.js
+1
-2
@@ -27,7 +27,6 @@ describe('ReactDOMNestedEvents', () => {
27
useState = React.useState;
28
});
29
30
- // @gate experimental
30
test('nested event dispatches should not cause updates to flush', async () => {
31
const buttonRef = React.createRef(null);
32
function App() {
@@ -58,7 +57,7 @@ describe('ReactDOMNestedEvents', () => {
57
58
const container = document.createElement('div');
59
document.body.appendChild(container);
61
- const root = ReactDOM.unstable_createRoot(container);
60
+ const root = ReactDOM.createRoot(container);
61
62
await act(async () => {
63
root.render(<App />);
packages/react-dom/src/__tests__/ReactDOMRoot-test.js
+20
-28
@@ -28,15 +28,8 @@ describe('ReactDOMRoot', () => {
28
act = require('react-dom/test-utils').unstable_concurrentAct;
29
});
30
31
- if (!__EXPERIMENTAL__) {
32
- it('createRoot is not exposed in stable build', () => {
33
- expect(ReactDOM.unstable_createRoot).toBe(undefined);
34
- });
35
- return;
36
- }
37
-
31
it('renders children', () => {
39
- const root = ReactDOM.unstable_createRoot(container);
32
+ const root = ReactDOM.createRoot(container);
33
root.render(<div>Hi</div>);
34
Scheduler.unstable_flushAll();
35
expect(container.textContent).toEqual('Hi');
@@ -44,7 +37,7 @@ describe('ReactDOMRoot', () => {
37
38
it('warns if a callback parameter is provided to render', () => {
39
const callback = jest.fn();
47
- const root = ReactDOM.unstable_createRoot(container);
40
+ const root = ReactDOM.createRoot(container);
41
expect(() =>
42
root.render(<div>Hi</div>, callback),
43
).toErrorDev(
@@ -58,7 +51,7 @@ describe('ReactDOMRoot', () => {
51
52
it('warns if a callback parameter is provided to unmount', () => {
53
const callback = jest.fn();
61
- const root = ReactDOM.unstable_createRoot(container);
54
+ const root = ReactDOM.createRoot(container);
55
root.render(<div>Hi</div>);
56
expect(() =>
57
root.unmount(callback),
@@ -72,7 +65,7 @@ describe('ReactDOMRoot', () => {
65
});
66
67
it('unmounts children', () => {
75
- const root = ReactDOM.unstable_createRoot(container);
68
+ const root = ReactDOM.createRoot(container);
69
root.render(<div>Hi</div>);
70
Scheduler.unstable_flushAll();
71
expect(container.textContent).toEqual('Hi');
@@ -95,7 +88,7 @@ describe('ReactDOMRoot', () => {
88
// Does not hydrate by default
89
const container1 = document.createElement('div');
90
container1.innerHTML = markup;
98
- const root1 = ReactDOM.unstable_createRoot(container1);
91
+ const root1 = ReactDOM.createRoot(container1);
92
root1.render(
93
<div>
94
<span />
@@ -106,7 +99,7 @@ describe('ReactDOMRoot', () => {
99
// Accepts `hydrate` option
100
const container2 = document.createElement('div');
101
container2.innerHTML = markup;
109
- const root2 = ReactDOM.unstable_createRoot(container2, {hydrate: true});
102
+ const root2 = ReactDOM.createRoot(container2, {hydrate: true});
103
root2.render(
104
<div>
105
<span />
@@ -138,7 +131,7 @@ describe('ReactDOMRoot', () => {
131
132
it('clears existing children', async () => {
133
container.innerHTML = '<div>a</div><div>b</div>';
141
- const root = ReactDOM.unstable_createRoot(container);
134
+ const root = ReactDOM.createRoot(container);
135
root.render(
136
<div>
137
<span>c</span>
@@ -159,12 +152,12 @@ describe('ReactDOMRoot', () => {
152
153
it('throws a good message on invalid containers', () => {
154
expect(() => {
162
- ReactDOM.unstable_createRoot(<div>Hi</div>);
155
+ ReactDOM.createRoot(<div>Hi</div>);
156
}).toThrow('createRoot(...): Target container is not a DOM element.');
157
});
158
159
it('warns when rendering with legacy API into createRoot() container', () => {
167
- const root = ReactDOM.unstable_createRoot(container);
160
+ const root = ReactDOM.createRoot(container);
161
root.render(<div>Hi</div>);
162
Scheduler.unstable_flushAll();
163
expect(container.textContent).toEqual('Hi');
@@ -187,7 +180,7 @@ describe('ReactDOMRoot', () => {
180
});
181
182
it('warns when hydrating with legacy API into createRoot() container', () => {
190
- const root = ReactDOM.unstable_createRoot(container);
183
+ const root = ReactDOM.createRoot(container);
184
root.render(<div>Hi</div>);
185
Scheduler.unstable_flushAll();
186
expect(container.textContent).toEqual('Hi');
@@ -207,7 +200,7 @@ describe('ReactDOMRoot', () => {
200
});
201
202
it('warns when unmounting with legacy API (no previous content)', () => {
210
- const root = ReactDOM.unstable_createRoot(container);
203
+ const root = ReactDOM.createRoot(container);
204
root.render(<div>Hi</div>);
205
Scheduler.unstable_flushAll();
206
expect(container.textContent).toEqual('Hi');
@@ -236,7 +229,7 @@ describe('ReactDOMRoot', () => {
229
// Currently createRoot().render() doesn't clear this.
230
container.appendChild(document.createElement('div'));
231
// The rest is the same as test above.
239
- const root = ReactDOM.unstable_createRoot(container);
232
+ const root = ReactDOM.createRoot(container);
233
root.render(<div>Hi</div>);
234
Scheduler.unstable_flushAll();
235
expect(container.textContent).toEqual('Hi');
@@ -262,7 +255,7 @@ describe('ReactDOMRoot', () => {
255
it('warns when passing legacy container to createRoot()', () => {
256
ReactDOM.render(<div>Hi</div>, container);
257
expect(() => {
265
- ReactDOM.unstable_createRoot(container);
258
+ ReactDOM.createRoot(container);
259
}).toErrorDev(
260
'You are calling ReactDOM.createRoot() on a container that was previously ' +
261
'passed to ReactDOM.render(). This is not supported.',
@@ -271,9 +264,9 @@ describe('ReactDOMRoot', () => {
264
});
265
266
it('warns when creating two roots managing the same container', () => {
274
- ReactDOM.unstable_createRoot(container);
267
+ ReactDOM.createRoot(container);
268
expect(() => {
276
- ReactDOM.unstable_createRoot(container);
269
+ ReactDOM.createRoot(container);
270
}).toErrorDev(
271
'You are calling ReactDOM.createRoot() on a container that ' +
272
'has already been passed to createRoot() before. Instead, call ' +
@@ -283,15 +276,15 @@ describe('ReactDOMRoot', () => {
276
});
277
278
it('does not warn when creating second root after first one is unmounted', () => {
286
- const root = ReactDOM.unstable_createRoot(container);
279
+ const root = ReactDOM.createRoot(container);
280
root.unmount();
281
Scheduler.unstable_flushAll();
289
- ReactDOM.unstable_createRoot(container); // No warning
282
+ ReactDOM.createRoot(container); // No warning
283
});
284
285
it('warns if creating a root on the document.body', async () => {
286
expect(() => {
294
- ReactDOM.unstable_createRoot(document.body);
287
+ ReactDOM.createRoot(document.body);
288
}).toErrorDev(
289
'createRoot(): Creating roots directly with document.body is ' +
290
'discouraged, since its children are often manipulated by third-party ' +
@@ -303,7 +296,7 @@ describe('ReactDOMRoot', () => {
296
});
297
298
it('warns if updating a root that has had its contents removed', async () => {
306
- const root = ReactDOM.unstable_createRoot(container);
299
+ const root = ReactDOM.createRoot(container);
300
root.render(<div>Hi</div>);
301
Scheduler.unstable_flushAll();
302
container.innerHTML = '';
@@ -319,9 +312,8 @@ describe('ReactDOMRoot', () => {
312
);
313
});
314
322
- // @gate experimental
315
it('opts-in to concurrent default updates', async () => {
324
- const root = ReactDOM.unstable_createRoot(container, {
316
+ const root = ReactDOM.createRoot(container, {
317
unstable_concurrentUpdatesByDefault: true,
318
});
319
packages/react-dom/src/__tests__/ReactDOMServerIntegrationHooks-test.js
+15
-39
@@ -895,7 +895,6 @@ describe('ReactDOMServerHooks', () => {
895
});
896
897
describe('useOpaqueIdentifier', () => {
898
- // @gate experimental
898
it('generates unique ids for server string render', async () => {
899
function App(props) {
900
const idOne = useOpaqueIdentifier();
@@ -929,7 +928,6 @@ describe('ReactDOMServerHooks', () => {
928
).not.toBeNull();
929
});
930
932
- // @gate experimental
931
it('generates unique ids for server stream render', async () => {
932
function App(props) {
933
const idOne = useOpaqueIdentifier();
@@ -963,7 +961,6 @@ describe('ReactDOMServerHooks', () => {
961
).not.toBeNull();
962
});
963
966
- // @gate experimental
964
it('generates unique ids for client render', async () => {
965
function App(props) {
966
const idOne = useOpaqueIdentifier();
@@ -997,7 +994,6 @@ describe('ReactDOMServerHooks', () => {
994
).not.toBeNull();
995
});
996
1000
- // @gate experimental
997
it('generates unique ids for client render on good server markup', async () => {
998
function App(props) {
999
const idOne = useOpaqueIdentifier();
@@ -1031,7 +1027,6 @@ describe('ReactDOMServerHooks', () => {
1027
).not.toBeNull();
1028
});
1029
1034
- // @gate experimental
1030
it('useOpaqueIdentifier does not change id even if the component updates during client render', async () => {
1031
let _setShowId;
1032
function App() {
@@ -1063,7 +1058,6 @@ describe('ReactDOMServerHooks', () => {
1058
);
1059
});
1060
1066
- // @gate experimental
1061
it('useOpaqueIdentifier identifierPrefix works for server renderer and does not clash', async () => {
1062
function ChildTwo({id}) {
1063
return <div id={id}>Child Three</div>;
@@ -1149,7 +1143,6 @@ describe('ReactDOMServerHooks', () => {
1143
).toBe(true);
1144
});
1145
1152
- // @gate experimental
1146
it('useOpaqueIdentifier identifierPrefix works for multiple reads on a streaming server renderer', async () => {
1147
function ChildTwo() {
1148
const id = useOpaqueIdentifier();
@@ -1241,7 +1234,6 @@ describe('ReactDOMServerHooks', () => {
1234
await Promise.all([streamOneIsDone, streamTwoIsDone]);
1235
});
1236
1244
- // @gate experimental
1237
it('useOpaqueIdentifier: IDs match when, after hydration, a new component that uses the ID is rendered', async () => {
1238
let _setShowDiv;
1239
function App() {
@@ -1261,7 +1253,7 @@ describe('ReactDOMServerHooks', () => {
1253
document.body.append(container);
1254
1255
container.innerHTML = ReactDOMServer.renderToString(<App />);
1264
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
1256
+ const root = ReactDOM.createRoot(container, {hydrate: true});
1257
root.render(<App />);
1258
Scheduler.unstable_flushAll();
1259
jest.runAllTimers();
@@ -1285,7 +1277,6 @@ describe('ReactDOMServerHooks', () => {
1277
).not.toBeNull();
1278
});
1279
1288
- // @gate experimental
1280
it('useOpaqueIdentifier: IDs match when, after hydration, a new component that uses the ID is rendered for legacy', async () => {
1281
let _setShowDiv;
1282
function App() {
@@ -1326,7 +1317,6 @@ describe('ReactDOMServerHooks', () => {
1317
).not.toBeNull();
1318
});
1319
1329
- // @gate experimental
1320
it('useOpaqueIdentifier: ID is not used during hydration but is used in an update', async () => {
1321
let _setShow;
1322
function App({unused}) {
@@ -1344,7 +1334,7 @@ describe('ReactDOMServerHooks', () => {
1334
const container = document.createElement('div');
1335
document.body.append(container);
1336
container.innerHTML = ReactDOMServer.renderToString(<App />);
1347
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
1337
+ const root = ReactDOM.createRoot(container, {hydrate: true});
1338
act(() => {
1339
root.render(<App />);
1340
});
@@ -1359,7 +1349,6 @@ describe('ReactDOMServerHooks', () => {
1349
).not.toBeNull();
1350
});
1351
1362
- // @gate experimental
1352
it('useOpaqueIdentifier: ID is not used during hydration but is used in an update in legacy', async () => {
1353
let _setShow;
1354
function App({unused}) {
@@ -1389,7 +1378,6 @@ describe('ReactDOMServerHooks', () => {
1378
).not.toBeNull();
1379
});
1380
1392
- // @gate experimental
1381
it('useOpaqueIdentifier: flushSync', async () => {
1382
let _setShow;
1383
function App() {
@@ -1406,7 +1394,7 @@ describe('ReactDOMServerHooks', () => {
1394
const container = document.createElement('div');
1395
document.body.append(container);
1396
container.innerHTML = ReactDOMServer.renderToString(<App />);
1409
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
1397
+ const root = ReactDOM.createRoot(container, {hydrate: true});
1398
act(() => {
1399
root.render(<App />);
1400
});
@@ -1422,7 +1410,6 @@ describe('ReactDOMServerHooks', () => {
1410
).not.toBeNull();
1411
});
1412
1425
- // @gate experimental
1413
it('useOpaqueIdentifier: children with id hydrates before other children if ID updates', async () => {
1414
let _setShow;
1415
@@ -1498,7 +1485,7 @@ describe('ReactDOMServerHooks', () => {
1485
.getAttribute('id');
1486
expect(serverId).not.toBeNull();
1487
1501
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
1488
+ const root = ReactDOM.createRoot(container, {hydrate: true});
1489
root.render(<App show={false} />);
1490
expect(Scheduler).toHaveYielded([]);
1491
@@ -1546,7 +1533,6 @@ describe('ReactDOMServerHooks', () => {
1533
expect(Scheduler).toHaveYielded([]);
1534
});
1535
1549
- // @gate experimental
1536
it('useOpaqueIdentifier: IDs match when part of the DOM tree is server rendered and part is client rendered', async () => {
1537
let suspend = true;
1538
let resolve;
@@ -1591,7 +1577,7 @@ describe('ReactDOMServerHooks', () => {
1577
container.innerHTML = ReactDOMServer.renderToString(<App />);
1578
1579
suspend = true;
1594
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
1580
+ const root = ReactDOM.createRoot(container, {hydrate: true});
1581
await act(async () => {
1582
root.render(<App />);
1583
});
@@ -1627,7 +1613,6 @@ describe('ReactDOMServerHooks', () => {
1613
).not.toBeNull();
1614
});
1615
1630
- // @gate experimental
1616
it('useOpaqueIdentifier warn when there is a hydration error', async () => {
1617
function Child({appId}) {
1618
return <div aria-labelledby={appId} />;
@@ -1642,7 +1627,7 @@ describe('ReactDOMServerHooks', () => {
1627
1628
// This is the wrong HTML string
1629
container.innerHTML = '<span></span>';
1645
- ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
1630
+ ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
1631
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
1632
[
1633
'Warning: An error occurred during hydration. The server HTML was replaced with client content in <div>.',
@@ -1652,7 +1637,6 @@ describe('ReactDOMServerHooks', () => {
1637
);
1638
});
1639
1655
- // @gate experimental
1640
it('useOpaqueIdentifier: IDs match when part of the DOM tree is server rendered and part is client rendered', async () => {
1641
let suspend = true;
1642
@@ -1695,7 +1679,7 @@ describe('ReactDOMServerHooks', () => {
1679
container.innerHTML = ReactDOMServer.renderToString(<App />);
1680
1681
suspend = false;
1698
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
1682
+ const root = ReactDOM.createRoot(container, {hydrate: true});
1683
await act(async () => {
1684
root.render(<App />);
1685
});
@@ -1717,7 +1701,6 @@ describe('ReactDOMServerHooks', () => {
1701
).not.toBeNull();
1702
});
1703
1720
- // @gate experimental
1704
it('useOpaqueIdentifier warn when there is a hydration error', async () => {
1705
function Child({appId}) {
1706
return <div aria-labelledby={appId} />;
@@ -1732,7 +1715,7 @@ describe('ReactDOMServerHooks', () => {
1715
1716
// This is the wrong HTML string
1717
container.innerHTML = '<span></span>';
1735
- ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
1718
+ ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
1719
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
1720
[
1721
'Warning: An error occurred during hydration. The server HTML was replaced with client content in <div>.',
@@ -1742,7 +1725,6 @@ describe('ReactDOMServerHooks', () => {
1725
);
1726
});
1727
1745
- // @gate experimental
1728
it('useOpaqueIdentifier warns when there is a hydration error and we are using ID as a string', async () => {
1729
function Child({appId}) {
1730
return <div aria-labelledby={appId + ''} />;
@@ -1757,7 +1739,7 @@ describe('ReactDOMServerHooks', () => {
1739
1740
// This is the wrong HTML string
1741
container.innerHTML = '<span></span>';
1760
- ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
1742
+ ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
1743
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
1744
[
1745
'Warning: The object passed back from useOpaqueIdentifier is meant to be passed through to attributes only. Do not read the value directly.',
@@ -1767,7 +1749,6 @@ describe('ReactDOMServerHooks', () => {
1749
);
1750
});
1751
1770
- // @gate experimental
1752
it('useOpaqueIdentifier warns when there is a hydration error and we are using ID as a string', async () => {
1753
function Child({appId}) {
1754
return <div aria-labelledby={appId + ''} />;
@@ -1782,7 +1763,7 @@ describe('ReactDOMServerHooks', () => {
1763
1764
// This is the wrong HTML string
1765
container.innerHTML = '<span></span>';
1785
- ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
1766
+ ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
1767
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
1768
[
1769
'Warning: The object passed back from useOpaqueIdentifier is meant to be passed through to attributes only. Do not read the value directly.',
@@ -1792,7 +1773,6 @@ describe('ReactDOMServerHooks', () => {
1773
);
1774
});
1775
1795
- // @gate experimental
1776
it('useOpaqueIdentifier warns if you try to use the result as a string in a child component', async () => {
1777
function Child({appId}) {
1778
return <div aria-labelledby={appId + ''} />;
@@ -1806,7 +1786,7 @@ describe('ReactDOMServerHooks', () => {
1786
document.body.appendChild(container);
1787
1788
container.innerHTML = ReactDOMServer.renderToString(<App />);
1809
- ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
1789
+ ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
1790
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
1791
[
1792
'Warning: The object passed back from useOpaqueIdentifier is meant to be passed through to attributes only. Do not read the value directly.',
@@ -1816,7 +1796,6 @@ describe('ReactDOMServerHooks', () => {
1796
);
1797
});
1798
1819
- // @gate experimental
1799
it('useOpaqueIdentifier warns if you try to use the result as a string', async () => {
1800
function App() {
1801
const id = useOpaqueIdentifier();
@@ -1827,7 +1806,7 @@ describe('ReactDOMServerHooks', () => {
1806
document.body.appendChild(container);
1807
1808
container.innerHTML = ReactDOMServer.renderToString(<App />);
1830
- ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
1809
+ ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
1810
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
1811
[
1812
'Warning: The object passed back from useOpaqueIdentifier is meant to be passed through to attributes only. Do not read the value directly.',
@@ -1837,7 +1816,6 @@ describe('ReactDOMServerHooks', () => {
1816
);
1817
});
1818
1840
- // @gate experimental
1819
it('useOpaqueIdentifier warns if you try to use the result as a string in a child component wrapped in a Suspense', async () => {
1820
function Child({appId}) {
1821
return <div aria-labelledby={appId + ''} />;
@@ -1856,7 +1834,7 @@ describe('ReactDOMServerHooks', () => {
1834
1835
container.innerHTML = ReactDOMServer.renderToString(<App />);
1836
1859
- ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
1837
+ ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
1838
1839
if (gate(flags => flags.deferRenderPhaseUpdateToNextBatch)) {
1840
expect(() => Scheduler.unstable_flushAll()).toErrorDev([
@@ -1878,7 +1856,6 @@ describe('ReactDOMServerHooks', () => {
1856
}
1857
});
1858
1881
- // @gate experimental
1859
it('useOpaqueIdentifier warns if you try to add the result as a number in a child component wrapped in a Suspense', async () => {
1860
function Child({appId}) {
1861
return <div aria-labelledby={+appId} />;
@@ -1899,7 +1876,7 @@ describe('ReactDOMServerHooks', () => {
1876
1877
container.innerHTML = ReactDOMServer.renderToString(<App />);
1878
1902
- ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
1879
+ ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
1880
1881
if (gate(flags => flags.deferRenderPhaseUpdateToNextBatch)) {
1882
expect(() => Scheduler.unstable_flushAll()).toErrorDev([
@@ -1921,7 +1898,6 @@ describe('ReactDOMServerHooks', () => {
1898
}
1899
});
1900
1924
- // @gate experimental
1901
it('useOpaqueIdentifier with two opaque identifiers on the same page', () => {
1902
let _setShow;
1903
@@ -1960,7 +1936,7 @@ describe('ReactDOMServerHooks', () => {
1936
.getAttribute('aria-labelledby'),
1937
).toEqual(serverID);
1938
1963
- ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
1939
+ ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
1940
jest.runAllTimers();
1941
expect(Scheduler).toHaveYielded([]);
1942
expect(Scheduler).toFlushAndYield([]);
packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js
+2
-35
@@ -102,7 +102,6 @@ describe('ReactDOMServerPartialHydration', () => {
102
);
103
}
104
105
- // @gate experimental
105
it('hydrates a parent even if a child Suspense boundary is blocked', async () => {
106
let suspend = false;
107
let resolve;
@@ -161,7 +160,6 @@ describe('ReactDOMServerPartialHydration', () => {
160
expect(ref.current).toBe(span);
161
});
162
164
- // @gate experimental
163
it('calls the hydration callbacks after hydration or deletion', async () => {
164
let suspend = false;
165
let resolve;
@@ -252,7 +250,6 @@ describe('ReactDOMServerPartialHydration', () => {
250
expect(deleted.length).toBe(1);
251
});
252
255
- // @gate experimental
253
it('calls the onDeleted hydration callback if the parent gets deleted', async () => {
254
let suspend = false;
255
const promise = new Promise(() => {});
@@ -310,7 +307,6 @@ describe('ReactDOMServerPartialHydration', () => {
307
expect(deleted.length).toBe(1);
308
});
309
313
- // @gate experimental || www
310
it('warns and replaces the boundary content in legacy mode', async () => {
311
let suspend = false;
312
let resolve;
@@ -390,7 +386,6 @@ describe('ReactDOMServerPartialHydration', () => {
386
expect(container.textContent).toBe('Hello');
387
});
388
393
- // @gate experimental
389
it('can insert siblings before the dehydrated boundary', () => {
390
let suspend = false;
391
const promise = new Promise(() => {});
@@ -449,7 +444,6 @@ describe('ReactDOMServerPartialHydration', () => {
444
expect(container.firstChild.firstChild.textContent).toBe('First');
445
});
446
452
- // @gate experimental
447
it('can delete the dehydrated boundary before it is hydrated', () => {
448
let suspend = false;
449
const promise = new Promise(() => {});
@@ -506,7 +500,6 @@ describe('ReactDOMServerPartialHydration', () => {
500
expect(container.firstChild.children[1].textContent).toBe('After');
501
});
502
509
- // @gate experimental
503
it('blocks updates to hydrate the content first if props have changed', async () => {
504
let suspend = false;
505
let resolve;
@@ -652,7 +645,6 @@ describe('ReactDOMServerPartialHydration', () => {
645
expect(span.className).toBe('hi');
646
});
647
655
- // @gate experimental
648
it('shows the fallback if props have changed before hydration completes and is still suspended', async () => {
649
let suspend = false;
650
let resolve;
@@ -722,7 +714,6 @@ describe('ReactDOMServerPartialHydration', () => {
714
expect(container.textContent).toBe('Hi');
715
});
716
725
- // @gate experimental
717
it('shows the fallback of the outer if fallback is missing', async () => {
718
// This is the same exact test as above but with a nested Suspense without a fallback.
719
// This should be a noop.
@@ -796,7 +787,6 @@ describe('ReactDOMServerPartialHydration', () => {
787
expect(container.textContent).toBe('Hi');
788
});
789
799
- // @gate experimental
790
it('clears nested suspense boundaries if they did not hydrate yet', async () => {
791
let suspend = false;
792
let resolve;
@@ -869,7 +859,6 @@ describe('ReactDOMServerPartialHydration', () => {
859
expect(container.textContent).toBe('Hi Hi');
860
});
861
872
- // @gate experimental
862
it('hydrates first if props changed but we are able to resolve within a timeout', async () => {
863
let suspend = false;
864
let resolve;
@@ -917,9 +906,7 @@ describe('ReactDOMServerPartialHydration', () => {
906
expect(container.textContent).toBe('Hello');
907
908
// Render an update with a long timeout.
920
- React.unstable_startTransition(() =>
921
- root.render(<App text="Hi" className="hi" />),
922
- );
909
+ React.startTransition(() => root.render(<App text="Hi" className="hi" />));
910
911
// This shouldn't force the fallback yet.
912
Scheduler.unstable_flushAll();
@@ -949,7 +936,6 @@ describe('ReactDOMServerPartialHydration', () => {
936
expect(span.className).toBe('hi');
937
});
938
952
- // @gate experimental
939
it('warns but works if setState is called before commit in a dehydrated component', async () => {
940
let suspend = false;
941
let resolve;
@@ -1018,7 +1004,6 @@ describe('ReactDOMServerPartialHydration', () => {
1004
expect(container.textContent).toBe('Hello');
1005
});
1006
1021
- // @gate experimental
1007
it('blocks the update to hydrate first if context has changed', async () => {
1008
let suspend = false;
1009
let resolve;
@@ -1103,7 +1088,6 @@ describe('ReactDOMServerPartialHydration', () => {
1088
expect(span.className).toBe('hi');
1089
});
1090
1106
- // @gate experimental
1091
it('shows the fallback if context has changed before hydration completes and is still suspended', async () => {
1092
let suspend = false;
1093
let resolve;
@@ -1187,7 +1171,6 @@ describe('ReactDOMServerPartialHydration', () => {
1171
expect(container.textContent).toBe('Hi');
1172
});
1173
1190
- // @gate experimental
1174
it('replaces the fallback with client content if it is not rendered by the server', async () => {
1175
let suspend = false;
1176
const promise = new Promise(resolvePromise => {});
@@ -1236,7 +1219,6 @@ describe('ReactDOMServerPartialHydration', () => {
1219
expect(ref.current).toBe(span);
1220
});
1221
1239
- // @gate experimental
1222
it('replaces the fallback within the suspended time if there is a nested suspense', async () => {
1223
let suspend = false;
1224
const promise = new Promise(resolvePromise => {});
@@ -1296,7 +1278,6 @@ describe('ReactDOMServerPartialHydration', () => {
1278
expect(ref.current).toBe(span);
1279
});
1280
1299
- // @gate experimental
1281
it('replaces the fallback within the suspended time if there is a nested suspense in a nested suspense', async () => {
1282
let suspend = false;
1283
const promise = new Promise(resolvePromise => {});
@@ -1358,7 +1339,6 @@ describe('ReactDOMServerPartialHydration', () => {
1339
expect(ref.current).toBe(span);
1340
});
1341
1361
- // @gate experimental
1342
it('shows inserted items in a SuspenseList before content is hydrated', async () => {
1343
let suspend = false;
1344
let resolve;
@@ -1444,7 +1424,6 @@ describe('ReactDOMServerPartialHydration', () => {
1424
expect(ref.current).toBe(spanB);
1425
});
1426
1447
- // @gate experimental
1427
it('shows is able to hydrate boundaries even if others in a list are pending', async () => {
1428
let suspend = false;
1429
let resolve;
@@ -1591,7 +1570,7 @@ describe('ReactDOMServerPartialHydration', () => {
1570
1571
await act(async () => {
1572
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1594
- React.unstable_startTransition(() => {
1573
+ React.startTransition(() => {
1574
root.render(<App />);
1575
});
1576
@@ -1622,7 +1601,6 @@ describe('ReactDOMServerPartialHydration', () => {
1601
expect(ref.current).toBe(b);
1602
});
1603
1625
- // @gate experimental
1604
it('clears server boundaries when SuspenseList suspends last row hydrating', async () => {
1605
let suspend = false;
1606
let resolve;
@@ -1679,7 +1657,6 @@ describe('ReactDOMServerPartialHydration', () => {
1657
expect(container.textContent).toBe('AB');
1658
});
1659
1682
- // @gate experimental
1660
it('can client render nested boundaries', async () => {
1661
let suspend = false;
1662
const promise = new Promise(() => {});
@@ -1734,7 +1711,6 @@ describe('ReactDOMServerPartialHydration', () => {
1711
expect(container.lastChild.data).toBe('unrelated comment');
1712
});
1713
1737
- // @gate experimental
1714
it('can hydrate TWO suspense boundaries', async () => {
1715
const ref1 = React.createRef();
1716
const ref2 = React.createRef();
@@ -1774,7 +1750,6 @@ describe('ReactDOMServerPartialHydration', () => {
1750
expect(ref2.current).toBe(span2);
1751
});
1752
1777
- // @gate experimental
1753
it('regenerates if it cannot hydrate before changes to props/context expire', async () => {
1754
let suspend = false;
1755
const promise = new Promise(resolvePromise => {});
@@ -1856,7 +1831,6 @@ describe('ReactDOMServerPartialHydration', () => {
1831
expect(newSpan.className).toBe('hi');
1832
});
1833
1859
- // @gate experimental
1834
it('does not invoke an event on a hydrated node until it commits', async () => {
1835
let suspend = false;
1836
let resolve;
@@ -2022,7 +1996,6 @@ describe('ReactDOMServerPartialHydration', () => {
1996
document.body.removeChild(container);
1997
});
1998
2025
- // @gate experimental
1999
it('invokes discrete events on nested suspense boundaries in a root (legacy system)', async () => {
2000
let suspend = false;
2001
let resolve;
@@ -2190,7 +2163,6 @@ describe('ReactDOMServerPartialHydration', () => {
2163
document.body.removeChild(container);
2164
});
2165
2193
- // @gate experimental
2166
it('does not invoke the parent of dehydrated boundary event', async () => {
2167
let suspend = false;
2168
let resolve;
@@ -2266,7 +2238,6 @@ describe('ReactDOMServerPartialHydration', () => {
2238
document.body.removeChild(container);
2239
});
2240
2269
- // @gate experimental
2241
it('does not invoke an event on a parent tree when a subtree is dehydrated', async () => {
2242
let suspend = false;
2243
let resolve;
@@ -2345,7 +2316,6 @@ describe('ReactDOMServerPartialHydration', () => {
2316
document.body.removeChild(parentContainer);
2317
});
2318
2348
- // @gate experimental
2319
it('blocks only on the last continuous event (legacy system)', async () => {
2320
let suspend1 = false;
2321
let resolve1;
@@ -2450,7 +2420,6 @@ describe('ReactDOMServerPartialHydration', () => {
2420
document.body.removeChild(container);
2421
});
2422
2453
- // @gate experimental
2423
it('finishes normal pri work before continuing to hydrate a retry', async () => {
2424
let suspend = false;
2425
let resolve;
@@ -2532,7 +2501,6 @@ describe('ReactDOMServerPartialHydration', () => {
2501
expect(ref.current).not.toBe(null);
2502
});
2503
2535
- // @gate experimental
2504
it('regression test: does not overfire non-bubbling browser events', async () => {
2505
let suspend = false;
2506
let resolve;
@@ -2623,7 +2591,6 @@ describe('ReactDOMServerPartialHydration', () => {
2591
// follow up.
2592
//
2593
// @gate FIXME
2626
- // @gate experimental
2594
it('hydrates a hidden subtree outside of a Suspense boundary', async () => {
2595
const ref = React.createRef();
2596
packages/react-dom/src/__tests__/ReactDOMServerSelectiveHydration-test.internal.js
-5
@@ -126,7 +126,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
126
IdleEventPriority = require('react-reconciler/constants').IdleEventPriority;
127
});
128
129
- // @gate experimental
129
it('hydrates the target boundary synchronously during a click', async () => {
130
function Child({text}) {
131
Scheduler.unstable_yieldValue(text);
@@ -189,7 +188,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
188
document.body.removeChild(container);
189
});
190
192
- // @gate experimental
191
it('hydrates at higher pri if sync did not work first time', async () => {
192
let suspend = false;
193
let resolve;
@@ -277,7 +275,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
275
document.body.removeChild(container);
276
});
277
280
- // @gate experimental
278
it('hydrates at higher pri for secondary discrete events', async () => {
279
let suspend = false;
280
let resolve;
@@ -628,7 +625,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
625
document.body.removeChild(container);
626
});
627
631
- // @gate experimental
628
it('hydrates the hovered targets as higher priority for continuous events', async () => {
629
let suspend = false;
630
let resolve;
@@ -731,7 +727,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
727
document.body.removeChild(container);
728
});
729
734
- // @gate experimental
730
it('hydrates the last target path first for continuous events', async () => {
731
let suspend = false;
732
let resolve;
packages/react-dom/src/__tests__/ReactDOMServerSuspense-test.internal.js
-4
@@ -93,7 +93,6 @@ describe('ReactDOMServerSuspense', () => {
93
: children;
94
}
95
96
- // @gate experimental || www
96
it('should render the children when no promise is thrown', async () => {
97
const c = await serverRender(
98
<div>
@@ -105,7 +104,6 @@ describe('ReactDOMServerSuspense', () => {
104
expect(getVisibleChildren(c)).toEqual(<div>Children</div>);
105
});
106
108
- // @gate experimental || www
107
it('should render the fallback when a promise thrown', async () => {
108
const c = await serverRender(
109
<div>
@@ -117,7 +115,6 @@ describe('ReactDOMServerSuspense', () => {
115
expect(getVisibleChildren(c)).toEqual(<div>Fallback</div>);
116
});
117
120
- // @gate experimental || www
118
it('should work with nested suspense components', async () => {
119
const c = await serverRender(
120
<div>
@@ -140,7 +137,6 @@ describe('ReactDOMServerSuspense', () => {
137
);
138
});
139
143
- // @gate experimental
140
it('server renders a SuspenseList component and its children', async () => {
141
const example = (
142
<React.SuspenseList>
packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js
+1
-2
@@ -492,12 +492,11 @@ describe('ReactDOMServerHydration', () => {
492
expect(element.textContent).toBe('Hello world');
493
});
494
495
- // @gate experimental
495
it('does not re-enter hydration after committing the first one', () => {
496
const finalHTML = ReactDOMServer.renderToString(<div />);
497
const container = document.createElement('div');
498
container.innerHTML = finalHTML;
500
- const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
499
+ const root = ReactDOM.createRoot(container, {hydrate: true});
500
root.render(<div />);
501
Scheduler.unstable_flushAll();
502
root.render(null);
packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js
+6
-9
@@ -29,7 +29,7 @@ describe('ReactTestUtils.act()', () => {
29
if (__EXPERIMENTAL__) {
30
let concurrentRoot = null;
31
const renderConcurrent = (el, dom) => {
32
- concurrentRoot = ReactDOM.unstable_createRoot(dom);
32
+ concurrentRoot = ReactDOM.createRoot(dom);
33
concurrentRoot.render(el);
34
};
35
@@ -96,20 +96,17 @@ describe('ReactTestUtils.act()', () => {
96
]);
97
});
98
99
- // @gate experimental
99
it('does not warn in concurrent mode', () => {
101
- const root = ReactDOM.unstable_createRoot(document.createElement('div'));
100
+ const root = ReactDOM.createRoot(document.createElement('div'));
101
root.render(<App />);
102
Scheduler.unstable_flushAll();
103
});
104
106
- // @gate experimental
105
it('warns in concurrent mode if root is strict', () => {
106
expect(() => {
109
- const root = ReactDOM.unstable_createRoot(
110
- document.createElement('div'),
111
- {unstable_strictMode: true},
112
- );
107
+ const root = ReactDOM.createRoot(document.createElement('div'), {
108
+ unstable_strictMode: true,
109
+ });
110
root.render(<App />);
111
Scheduler.unstable_flushAll();
112
}).toErrorDev([
@@ -665,7 +662,7 @@ function runActTests(label, render, unmount, rerender) {
662
expect(document.querySelector('[data-test-id=spinner]')).toBeNull();
663
664
// trigger a suspendy update with a delay
668
- React.unstable_startTransition(() => {
665
+ React.startTransition(() => {
666
act(() => {
667
rerender(<App suspend={true} />);
668
});
packages/react-dom/src/__tests__/ReactUnmockedSchedulerWarning-test.js
+2
-3
@@ -29,10 +29,9 @@ it('does not warn when rendering in legacy mode', () => {
29
}).toErrorDev([]);
30
});
31
32
-// @gate experimental
32
it('should warn when rendering in concurrent mode', () => {
33
expect(() => {
35
- ReactDOM.unstable_createRoot(document.createElement('div')).render(<App />);
34
+ ReactDOM.createRoot(document.createElement('div')).render(<App />);
35
}).toErrorDev(
36
'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' +
37
'to guarantee consistent behaviour across tests and browsers.',
@@ -40,6 +39,6 @@ it('should warn when rendering in concurrent mode', () => {
39
);
40
// does not warn twice
41
expect(() => {
43
- ReactDOM.unstable_createRoot(document.createElement('div')).render(<App />);
42
+ ReactDOM.createRoot(document.createElement('div')).render(<App />);
43
}).toErrorDev([]);
44
});
packages/react-dom/src/__tests__/ReactUpdates-test.js
+1
-1
@@ -1332,7 +1332,7 @@ describe('ReactUpdates', () => {
1332
);
1333
}
1334
1335
- const root = ReactDOM.unstable_createRoot(container);
1335
+ const root = ReactDOM.createRoot(container);
1336
let hiddenDiv;
1337
act(() => {
1338
root.render(<Foo />);
packages/react-dom/src/__tests__/ReactWrongReturnPointer-test.js
+1
-1
@@ -22,7 +22,7 @@ beforeEach(() => {
22
Scheduler = require('scheduler');
23
24
Suspense = React.Suspense;
25
- SuspenseList = React.unstable_SuspenseList;
25
+ SuspenseList = React.SuspenseList;
26
27
getCacheForType = React.unstable_getCacheForType;
28
packages/react-dom/src/client/ReactDOM.js
-24
@@ -78,7 +78,6 @@ setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority);
78
setGetCurrentUpdatePriority(getCurrentUpdatePriority);
79
setAttemptHydrationAtPriority(runWithPriority);
80
81
-let didWarnAboutUnstableCreatePortal = false;
81
let didWarnAboutUnstableRenderSubtreeIntoContainer = false;
82
83
if (__DEV__) {
@@ -155,25 +154,6 @@ function renderSubtreeIntoContainer(
154
);
155
}
156
158
-function unstable_createPortal(
159
- children: ReactNodeList,
160
- container: Container,
161
- key: ?string = null,
162
-) {
163
- if (__DEV__) {
164
- if (!didWarnAboutUnstableCreatePortal) {
165
- didWarnAboutUnstableCreatePortal = true;
166
- console.warn(
167
- 'The ReactDOM.unstable_createPortal() alias has been deprecated, ' +
168
- 'and will be removed in React 18+. Update your code to use ' +
169
- 'ReactDOM.createPortal() instead. It has the exact same API, ' +
170
- 'but without the "unstable_" prefix.',
171
- );
172
- }
173
- }
174
- return createPortal(children, container, key);
175
-}
176
-
157
const Internals = {
158
// Keep in sync with ReactTestUtils.js, and ReactTestUtilsAct.js.
159
// This is an array for better minification.
@@ -206,10 +186,6 @@ export {
186
scheduleHydration as unstable_scheduleHydration,
187
// Disabled behind disableUnstableRenderSubtreeIntoContainer
188
renderSubtreeIntoContainer as unstable_renderSubtreeIntoContainer,
209
- // Disabled behind disableUnstableCreatePortal
210
- // Temporary alias since we already shipped React 16 RC with it.
211
- // TODO: remove in React 18.
212
- unstable_createPortal,
189
// enableCreateEventHandleAPI
190
createEventHandle as unstable_createEventHandle,
191
// TODO: Remove this once callers migrate to alternatives.
packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js
+1
-2
@@ -575,7 +575,6 @@ describe('DOMPluginEventSystem', () => {
575
expect(log).toEqual(['second', 'first']);
576
});
577
578
- // @gate experimental
578
it('does not invoke an event on a parent tree when a subtree is dehydrated', async () => {
579
let suspend = false;
580
let resolve;
@@ -1951,7 +1950,7 @@ describe('DOMPluginEventSystem', () => {
1950
1951
// Increase counter
1952
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1954
- React.unstable_startTransition(() => {
1953
+ React.startTransition(() => {
1954
root.render(<Test counter={1} />);
1955
});
1956
} else {
packages/react-dom/src/events/plugins/__tests__/ChangeEventPlugin-test.js
+6
-12
@@ -495,9 +495,8 @@ describe('ChangeEventPlugin', () => {
495
});
496
497
describe('concurrent mode', () => {
498
- // @gate experimental
498
it('text input', () => {
500
- const root = ReactDOM.unstable_createRoot(container);
499
+ const root = ReactDOM.createRoot(container);
500
let input;
501
502
class ControlledInput extends React.Component {
@@ -538,9 +537,8 @@ describe('ChangeEventPlugin', () => {
537
expect(input.value).toBe('changed [!]');
538
});
539
541
- // @gate experimental
540
it('checkbox input', () => {
543
- const root = ReactDOM.unstable_createRoot(container);
541
+ const root = ReactDOM.createRoot(container);
542
let input;
543
544
class ControlledInput extends React.Component {
@@ -594,9 +592,8 @@ describe('ChangeEventPlugin', () => {
592
expect(input.checked).toBe(false);
593
});
594
597
- // @gate experimental
595
it('textarea', () => {
599
- const root = ReactDOM.unstable_createRoot(container);
596
+ const root = ReactDOM.createRoot(container);
597
let textarea;
598
599
class ControlledTextarea extends React.Component {
@@ -637,9 +634,8 @@ describe('ChangeEventPlugin', () => {
634
expect(textarea.value).toBe('changed [!]');
635
});
636
640
- // @gate experimental
637
it('parent of input', () => {
642
- const root = ReactDOM.unstable_createRoot(container);
638
+ const root = ReactDOM.createRoot(container);
639
let input;
640
641
class ControlledInput extends React.Component {
@@ -684,9 +680,8 @@ describe('ChangeEventPlugin', () => {
680
expect(input.value).toBe('changed [!]');
681
});
682
687
- // @gate experimental
683
it('is sync for non-input events', async () => {
689
- const root = ReactDOM.unstable_createRoot(container);
684
+ const root = ReactDOM.createRoot(container);
685
let input;
686
687
class ControlledInput extends React.Component {
@@ -731,12 +726,11 @@ describe('ChangeEventPlugin', () => {
726
expect(input.value).toBe('');
727
});
728
734
- // @gate experimental
729
it('mouse enter/leave should be user-blocking but not discrete', async () => {
730
const {unstable_concurrentAct: act} = TestUtils;
731
const {useState} = React;
732
739
- const root = ReactDOM.unstable_createRoot(container);
733
+ const root = ReactDOM.createRoot(container);
734
735
const target = React.createRef(null);
736
function Foo() {
packages/react-dom/src/events/plugins/__tests__/SimpleEventPlugin-test.js
+2
-4
@@ -240,10 +240,9 @@ describe('SimpleEventPlugin', function() {
240
act = require('react-dom/test-utils').unstable_concurrentAct;
241
});
242
243
- // @gate experimental
243
it('flushes pending interactive work before exiting event handler', async () => {
244
container = document.createElement('div');
246
- const root = ReactDOM.unstable_createRoot(container);
245
+ const root = ReactDOM.createRoot(container);
246
document.body.appendChild(container);
247
248
let button;
@@ -316,10 +315,9 @@ describe('SimpleEventPlugin', function() {
315
// NOTE: This test was written for the old behavior of discrete updates,
316
// where they would be async, but flushed early if another discrete update
317
// was dispatched.
319
- // @gate experimental
318
it('end result of many interactive updates is deterministic', async () => {
319
container = document.createElement('div');
322
- const root = ReactDOM.unstable_createRoot(container);
320
+ const root = ReactDOM.createRoot(container);
321
document.body.appendChild(container);
322
323
let button;
packages/react-is/index.experimental.js
+2
-2
@@ -23,7 +23,7 @@ export {
23
Profiler,
24
StrictMode,
25
Suspense,
26
- unstable_SuspenseList,
26
+ SuspenseList,
27
isAsyncMode,
28
isConcurrentMode,
29
isContextConsumer,
@@ -37,5 +37,5 @@ export {
37
isProfiler,
38
isStrictMode,
39
isSuspense,
40
- unstable_isSuspenseList,
40
+ isSuspenseList,
41
} from './src/ReactIs';
packages/react-is/index.stable.js
+2
@@ -23,6 +23,7 @@ export {
23
Profiler,
24
StrictMode,
25
Suspense,
26
+ SuspenseList,
27
isAsyncMode,
28
isConcurrentMode,
29
isContextConsumer,
@@ -36,4 +37,5 @@ export {
37
isProfiler,
38
isStrictMode,
39
isSuspense,
40
+ isSuspenseList,
41
} from './src/ReactIs';
packages/react-is/src/ReactIs.js
+2
-2
@@ -72,7 +72,7 @@ export const Portal = REACT_PORTAL_TYPE;
72
export const Profiler = REACT_PROFILER_TYPE;
73
export const StrictMode = REACT_STRICT_MODE_TYPE;
74
export const Suspense = REACT_SUSPENSE_TYPE;
75
-export const unstable_SuspenseList = REACT_SUSPENSE_LIST_TYPE;
75
+export const SuspenseList = REACT_SUSPENSE_LIST_TYPE;
76
77
export {isValidElementType};
78
@@ -143,6 +143,6 @@ export function isStrictMode(object: any) {
143
export function isSuspense(object: any) {
144
return typeOf(object) === REACT_SUSPENSE_TYPE;
145
}
146
-export function unstable_isSuspenseList(object: any) {
146
+export function isSuspenseList(object: any) {
147
return typeOf(object) === REACT_SUSPENSE_LIST_TYPE;
148
}
packages/react-is/src/__tests__/ReactIs-test.js
+6
-15
@@ -186,22 +186,13 @@ describe('ReactIs', () => {
186
expect(ReactIs.isSuspense(<div />)).toBe(false);
187
});
188
189
- // @gate experimental
189
it('should identify suspense list', () => {
191
- expect(ReactIs.isValidElementType(React.unstable_SuspenseList)).toBe(true);
192
- expect(ReactIs.typeOf(<React.unstable_SuspenseList />)).toBe(
193
- ReactIs.unstable_SuspenseList,
194
- );
195
- expect(
196
- ReactIs.unstable_isSuspenseList(<React.unstable_SuspenseList />),
197
- ).toBe(true);
198
- expect(
199
- ReactIs.unstable_isSuspenseList({type: ReactIs.unstable_SuspenseList}),
200
- ).toBe(false);
201
- expect(ReactIs.unstable_isSuspenseList('React.unstable_SuspenseList')).toBe(
202
- false,
203
- );
204
- expect(ReactIs.unstable_isSuspenseList(<div />)).toBe(false);
190
+ expect(ReactIs.isValidElementType(React.SuspenseList)).toBe(true);
191
+ expect(ReactIs.typeOf(<React.SuspenseList />)).toBe(ReactIs.SuspenseList);
192
+ expect(ReactIs.isSuspenseList(<React.SuspenseList />)).toBe(true);
193
+ expect(ReactIs.isSuspenseList({type: ReactIs.SuspenseList})).toBe(false);
194
+ expect(ReactIs.isSuspenseList('React.SuspenseList')).toBe(false);
195
+ expect(ReactIs.isSuspenseList(<div />)).toBe(false);
196
});
197
198
it('should identify profile root', () => {
packages/react-reconciler/src/__tests__/ReactCache-test.js
+1
-1
@@ -22,7 +22,7 @@ describe('ReactCache', () => {
22
Suspense = React.Suspense;
23
getCacheForType = React.unstable_getCacheForType;
24
useCacheRefresh = React.unstable_useCacheRefresh;
25
- startTransition = React.unstable_startTransition;
25
+ startTransition = React.startTransition;
26
useState = React.useState;
27
28
caches = [];
packages/react-reconciler/src/__tests__/ReactContextPropagation-test.js
+1
-3
@@ -19,7 +19,7 @@ describe('ReactLazyContextPropagation', () => {
19
useState = React.useState;
20
useContext = React.useContext;
21
Suspense = React.Suspense;
22
- SuspenseList = React.unstable_SuspenseList;
22
+ SuspenseList = React.SuspenseList;
23
24
getCacheForType = React.unstable_getCacheForType;
25
@@ -649,8 +649,6 @@ describe('ReactLazyContextPropagation', () => {
649
expect(root).toMatchRenderedOutput('BBB');
650
});
651
652
- // @gate enableCache
653
- // @gate experimental
652
test('contexts are propagated through SuspenseList', async () => {
653
// This kinda tests an implementation detail. SuspenseList has an early
654
// bailout that doesn't use `bailoutOnAlreadyFinishedWork`. It probably
packages/react-reconciler/src/__tests__/ReactDisableSchedulerTimeoutBasedOnReactExpirationTime-test.internal.js
+1
-2
@@ -45,7 +45,6 @@ describe('ReactSuspenseList', () => {
45
return Component;
46
}
47
48
- // @gate experimental || !enableSyncDefaultUpdates
48
it('appends rendering tasks to the end of the priority queue', async () => {
49
const A = createAsyncText('A');
50
const B = createAsyncText('B');
@@ -65,7 +64,7 @@ describe('ReactSuspenseList', () => {
64
expect(Scheduler).toFlushAndYield([]);
65
66
if (gate(flags => flags.enableSyncDefaultUpdates)) {
68
- React.unstable_startTransition(() => {
67
+ React.startTransition(() => {
68
root.render(<App show={true} />);
69
});
70
} else {
packages/react-reconciler/src/__tests__/ReactExpiration-test.js
+14
-26
@@ -25,7 +25,7 @@ describe('ReactExpiration', () => {
25
React = require('react');
26
ReactNoop = require('react-noop-renderer');
27
Scheduler = require('scheduler');
28
- startTransition = React.unstable_startTransition;
28
+ startTransition = React.startTransition;
29
useState = React.useState;
30
useEffect = React.useEffect;
31
@@ -115,10 +115,10 @@ describe('ReactExpiration', () => {
115
// Flush the sync task.
116
ReactNoop.flushSync();
117
}
118
- // @gate experimental || !enableSyncDefaultUpdates
118
+
119
it('increases priority of updates as time progresses', () => {
120
if (gate(flags => flags.enableSyncDefaultUpdates)) {
121
- React.unstable_startTransition(() => {
121
+ React.startTransition(() => {
122
ReactNoop.render(<span prop="done" />);
123
});
124
} else {
@@ -142,7 +142,6 @@ describe('ReactExpiration', () => {
142
expect(ReactNoop.getChildren()).toEqual([span('done')]);
143
});
144
145
- // @gate experimental || !enableSyncDefaultUpdates
145
it('two updates of like priority in the same event always flush within the same batch', () => {
146
class TextClass extends React.Component {
147
componentDidMount() {
@@ -166,7 +165,7 @@ describe('ReactExpiration', () => {
165
// First, show what happens for updates in two separate events.
166
// Schedule an update.
167
if (gate(flags => flags.enableSyncDefaultUpdates)) {
169
- React.unstable_startTransition(() => {
168
+ React.startTransition(() => {
169
ReactNoop.render(<TextClass text="A" />);
170
});
171
} else {
@@ -201,7 +200,6 @@ describe('ReactExpiration', () => {
200
expect(Scheduler).toFlushAndYield(['B [render]', 'B [commit]']);
201
});
202
204
- // @gate experimental || !enableSyncDefaultUpdates
203
it(
204
'two updates of like priority in the same event always flush within the ' +
205
"same batch, even if there's a sync update in between",
@@ -228,7 +226,7 @@ describe('ReactExpiration', () => {
226
// First, show what happens for updates in two separate events.
227
// Schedule an update.
228
if (gate(flags => flags.enableSyncDefaultUpdates)) {
231
- React.unstable_startTransition(() => {
229
+ React.startTransition(() => {
230
ReactNoop.render(<TextClass text="A" />);
231
});
232
} else {
@@ -269,7 +267,6 @@ describe('ReactExpiration', () => {
267
},
268
);
269
272
- // @gate experimental || !enableSyncDefaultUpdates
270
it('cannot update at the same expiration time that is already rendering', () => {
271
const store = {text: 'initial'};
272
const subscribers = [];
@@ -307,7 +304,7 @@ describe('ReactExpiration', () => {
304
305
// Initial mount
306
if (gate(flags => flags.enableSyncDefaultUpdates)) {
310
- React.unstable_startTransition(() => {
307
+ React.startTransition(() => {
308
ReactNoop.render(<App />);
309
});
310
} else {
@@ -326,7 +323,7 @@ describe('ReactExpiration', () => {
323
324
// Partial update
325
if (gate(flags => flags.enableSyncDefaultUpdates)) {
329
- React.unstable_startTransition(() => {
326
+ React.startTransition(() => {
327
subscribers.forEach(s => s.setState({text: '1'}));
328
});
329
} else {
@@ -347,7 +344,6 @@ describe('ReactExpiration', () => {
344
]);
345
});
346
350
- // @gate experimental || !enableSyncDefaultUpdates
347
it('stops yielding if CPU-bound update takes too long to finish', () => {
348
const root = ReactNoop.createRoot();
349
function App() {
@@ -363,7 +359,7 @@ describe('ReactExpiration', () => {
359
}
360
361
if (gate(flags => flags.enableSyncDefaultUpdates)) {
366
- React.unstable_startTransition(() => {
362
+ React.startTransition(() => {
363
root.render(<App />);
364
});
365
} else {
@@ -381,7 +377,6 @@ describe('ReactExpiration', () => {
377
expect(root).toMatchRenderedOutput('ABCDE');
378
});
379
384
- // @gate experimental || !enableSyncDefaultUpdates
380
it('root expiration is measured from the time of the first update', () => {
381
Scheduler.unstable_advanceTime(10000);
382
@@ -398,7 +393,7 @@ describe('ReactExpiration', () => {
393
);
394
}
395
if (gate(flags => flags.enableSyncDefaultUpdates)) {
401
- React.unstable_startTransition(() => {
396
+ React.startTransition(() => {
397
root.render(<App />);
398
});
399
} else {
@@ -416,7 +411,6 @@ describe('ReactExpiration', () => {
411
expect(root).toMatchRenderedOutput('ABCDE');
412
});
413
419
- // @gate experimental || !enableSyncDefaultUpdates
414
it('should measure expiration times relative to module initialization', () => {
415
// Tests an implementation detail where expiration times are computed using
416
// bitwise operations.
@@ -433,7 +427,7 @@ describe('ReactExpiration', () => {
427
ReactNoop = require('react-noop-renderer');
428
429
if (gate(flags => flags.enableSyncDefaultUpdates)) {
436
- React.unstable_startTransition(() => {
430
+ React.startTransition(() => {
431
ReactNoop.render('Hi');
432
});
433
} else {
@@ -453,7 +447,6 @@ describe('ReactExpiration', () => {
447
expect(ReactNoop).toMatchRenderedOutput('Hi');
448
});
449
456
- // @gate experimental || !enableSyncDefaultUpdates
450
it('should measure callback timeout relative to current time, not start-up time', () => {
451
// Corresponds to a bugfix: https://github.com/facebook/react/pull/15479
452
// The bug wasn't caught by other tests because we use virtual times that
@@ -463,7 +456,7 @@ describe('ReactExpiration', () => {
456
Scheduler.unstable_advanceTime(10000);
457
458
if (gate(flags => flags.enableSyncDefaultUpdates)) {
466
- React.unstable_startTransition(() => {
459
+ React.startTransition(() => {
460
ReactNoop.render('Hi');
461
});
462
} else {
@@ -481,7 +474,6 @@ describe('ReactExpiration', () => {
474
expect(ReactNoop).toMatchRenderedOutput('Hi');
475
});
476
484
- // @gate experimental || !enableSyncDefaultUpdates
477
it('prevents starvation by sync updates by disabling time slicing if too much time has elapsed', async () => {
478
let updateSyncPri;
479
let updateNormalPri;
@@ -513,7 +505,7 @@ describe('ReactExpiration', () => {
505
// First demonstrate what happens when there's no starvation
506
await ReactNoop.act(async () => {
507
if (gate(flags => flags.enableSyncDefaultUpdates)) {
516
- React.unstable_startTransition(() => {
508
+ React.startTransition(() => {
509
updateNormalPri();
510
});
511
} else {
@@ -537,7 +529,7 @@ describe('ReactExpiration', () => {
529
// Do the same thing, but starve the first update
530
await ReactNoop.act(async () => {
531
if (gate(flags => flags.enableSyncDefaultUpdates)) {
540
- React.unstable_startTransition(() => {
532
+ React.startTransition(() => {
533
updateNormalPri();
534
});
535
} else {
@@ -628,7 +620,6 @@ describe('ReactExpiration', () => {
620
expect(root).toMatchRenderedOutput('Sync pri: 2, Idle pri: 2');
621
});
622
631
- // @gate experimental
623
it('when multiple lanes expire, we can finish the in-progress one without including the others', async () => {
624
let setA;
625
let setB;
@@ -677,7 +668,6 @@ describe('ReactExpiration', () => {
668
});
669
});
670
680
- // @gate experimental || !enableSyncDefaultUpdates
671
it('updates do not expire while they are IO-bound', async () => {
672
const {Suspense} = React;
673
@@ -701,7 +691,7 @@ describe('ReactExpiration', () => {
691
692
await ReactNoop.act(async () => {
693
if (gate(flags => flags.enableSyncDefaultUpdates)) {
704
- React.unstable_startTransition(() => {
694
+ React.startTransition(() => {
695
root.render(<App step={1} />);
696
});
697
} else {
@@ -734,7 +724,6 @@ describe('ReactExpiration', () => {
724
});
725
});
726
737
- // @gate experimental
727
it('flushSync should not affect expired work', async () => {
728
let setA;
729
let setB;
@@ -778,7 +767,6 @@ describe('ReactExpiration', () => {
767
});
768
});
769
781
- // @gate experimental
770
it('passive effects of expired update flush after paint', async () => {
771
function App({step}) {
772
useEffect(() => {
packages/react-reconciler/src/__tests__/ReactFlushSync-test.js
+2
-4
@@ -14,7 +14,7 @@ describe('ReactFlushSync', () => {
14
Scheduler = require('scheduler');
15
useState = React.useState;
16
useEffect = React.useEffect;
17
- startTransition = React.unstable_startTransition;
17
+ startTransition = React.startTransition;
18
});
19
20
function Text({text}) {
@@ -22,7 +22,6 @@ describe('ReactFlushSync', () => {
22
return text;
23
}
24
25
- // @gate experimental || !enableSyncDefaultUpdates
25
test('changes priority of updates in useEffect', async () => {
26
function App() {
27
const [syncState, setSyncState] = useState(0);
@@ -39,7 +38,7 @@ describe('ReactFlushSync', () => {
38
const root = ReactNoop.createRoot();
39
await ReactNoop.act(async () => {
40
if (gate(flags => flags.enableSyncDefaultUpdates)) {
42
- React.unstable_startTransition(() => {
41
+ React.startTransition(() => {
42
root.render(<App />);
43
});
44
} else {
@@ -64,7 +63,6 @@ describe('ReactFlushSync', () => {
63
expect(root).toMatchRenderedOutput('1, 1');
64
});
65
67
- // @gate experimental
66
test('nested with startTransition', async () => {
67
let setSyncState;
68
let setState;
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
+13
-21
@@ -52,8 +52,8 @@ describe('ReactHooksWithNoopRenderer', () => {
52
useImperativeHandle = React.useImperativeHandle;
53
forwardRef = React.forwardRef;
54
memo = React.memo;
55
- useTransition = React.unstable_useTransition;
56
- useDeferredValue = React.unstable_useDeferredValue;
55
+ useTransition = React.useTransition;
56
+ useDeferredValue = React.useDeferredValue;
57
Suspense = React.Suspense;
58
act = ReactNoop.act;
59
ContinuousEventPriority = require('react-reconciler/constants')
@@ -149,7 +149,6 @@ describe('ReactHooksWithNoopRenderer', () => {
149
return Promise.resolve().then(() => {});
150
}
151
152
- // @gate experimental || !enableSyncDefaultUpdates
152
it('resumes after an interruption', () => {
153
function Counter(props, ref) {
154
const [count, updateCount] = useState(0);
@@ -166,7 +165,7 @@ describe('ReactHooksWithNoopRenderer', () => {
165
166
// Schedule some updates
167
if (gate(flags => flags.enableSyncDefaultUpdates)) {
169
- React.unstable_startTransition(() => {
168
+ React.startTransition(() => {
169
// TODO: Batched updates need to be inside startTransition?
170
ReactNoop.batchedUpdates(() => {
171
counter.current.updateCount(1);
@@ -691,7 +690,6 @@ describe('ReactHooksWithNoopRenderer', () => {
690
expect(ReactNoop.getChildren()).toEqual([span(22)]);
691
});
692
694
- // @gate experimental || !enableSyncDefaultUpdates
693
it('discards render phase updates if something suspends', async () => {
694
const thenable = {then() {}};
695
function Foo({signal}) {
@@ -728,7 +726,7 @@ describe('ReactHooksWithNoopRenderer', () => {
726
expect(root).toMatchRenderedOutput(<span prop={0} />);
727
728
if (gate(flags => flags.enableSyncDefaultUpdates)) {
731
- React.unstable_startTransition(() => {
729
+ React.startTransition(() => {
730
root.render(<Foo signal={false} />);
731
});
732
} else {
@@ -739,7 +737,7 @@ describe('ReactHooksWithNoopRenderer', () => {
737
738
// Rendering again should suspend again.
739
if (gate(flags => flags.enableSyncDefaultUpdates)) {
742
- React.unstable_startTransition(() => {
740
+ React.startTransition(() => {
741
root.render(<Foo signal={false} />);
742
});
743
} else {
@@ -748,7 +746,6 @@ describe('ReactHooksWithNoopRenderer', () => {
746
expect(Scheduler).toFlushAndYield(['Suspend!']);
747
});
748
751
- // @gate experimental || !enableSyncDefaultUpdates
749
it('discards render phase updates if something suspends, but not other updates in the same component', async () => {
750
const thenable = {then() {}};
751
function Foo({signal}) {
@@ -792,7 +789,7 @@ describe('ReactHooksWithNoopRenderer', () => {
789
790
await ReactNoop.act(async () => {
791
if (gate(flags => flags.enableSyncDefaultUpdates)) {
795
- React.unstable_startTransition(() => {
792
+ React.startTransition(() => {
793
root.render(<Foo signal={false} />);
794
setLabel('B');
795
});
@@ -806,7 +803,7 @@ describe('ReactHooksWithNoopRenderer', () => {
803
804
// Rendering again should suspend again.
805
if (gate(flags => flags.enableSyncDefaultUpdates)) {
809
- React.unstable_startTransition(() => {
806
+ React.startTransition(() => {
807
root.render(<Foo signal={false} />);
808
});
809
} else {
@@ -817,7 +814,7 @@ describe('ReactHooksWithNoopRenderer', () => {
814
// Flip the signal back to "cancel" the update. However, the update to
815
// label should still proceed. It shouldn't have been dropped.
816
if (gate(flags => flags.enableSyncDefaultUpdates)) {
820
- React.unstable_startTransition(() => {
817
+ React.startTransition(() => {
818
root.render(<Foo signal={true} />);
819
});
820
} else {
@@ -864,13 +861,12 @@ describe('ReactHooksWithNoopRenderer', () => {
861
});
862
863
// TODO: This should probably warn
867
- // @gate experimental
864
it('calling startTransition inside render phase', async () => {
865
function App() {
866
const [counter, setCounter] = useState(0);
867
868
if (counter === 0) {
873
- React.unstable_startTransition(() => {
869
+ React.startTransition(() => {
870
setCounter(c => c + 1);
871
});
872
}
@@ -1315,7 +1311,6 @@ describe('ReactHooksWithNoopRenderer', () => {
1311
});
1312
});
1313
1318
- // @gate experimental || !enableSyncDefaultUpdates
1314
it('does not warn about state updates for unmounted components with pending passive unmounts for alternates', () => {
1315
let setParentState = null;
1316
const setChildStates = [];
@@ -1383,7 +1378,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1378
1379
// Schedule another update for children, and partially process it.
1380
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1386
- React.unstable_startTransition(() => {
1381
+ React.startTransition(() => {
1382
setChildStates.forEach(setChildState => setChildState(2));
1383
});
1384
} else {
@@ -1685,7 +1680,6 @@ describe('ReactHooksWithNoopRenderer', () => {
1680
});
1681
});
1682
1688
- // @gate experimental || !enableSyncDefaultUpdates
1683
it('updates have async priority even if effects are flushed early', () => {
1684
function Counter(props) {
1685
const [count, updateCount] = useState('(empty)');
@@ -1707,7 +1701,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1701
1702
// Rendering again should flush the previous commit's effects
1703
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1710
- React.unstable_startTransition(() => {
1704
+ React.startTransition(() => {
1705
ReactNoop.render(<Counter count={1} />, () =>
1706
Scheduler.unstable_yieldValue('Sync effect'),
1707
);
@@ -3127,8 +3121,8 @@ describe('ReactHooksWithNoopRenderer', () => {
3121
expect(totalRefUpdates).toBe(2); // Should not increase since last time
3122
});
3123
});
3124
+
3125
describe('useTransition', () => {
3131
- // @gate experimental
3126
it('delays showing loading state until after timeout', async () => {
3127
let transition;
3128
function App() {
@@ -3190,7 +3184,6 @@ describe('ReactHooksWithNoopRenderer', () => {
3184
});
3185
3186
describe('useDeferredValue', () => {
3193
- // @gate experimental
3187
it('defers text value', async () => {
3188
function TextBox({text}) {
3189
return <AsyncText text={text} />;
@@ -3694,9 +3687,8 @@ describe('ReactHooksWithNoopRenderer', () => {
3687
]);
3688
});
3689
3697
- // @gate experimental
3690
it('regression: SuspenseList causes unmounts to be dropped on deletion', async () => {
3699
- const SuspenseList = React.unstable_SuspenseList;
3691
+ const SuspenseList = React.SuspenseList;
3692
3693
function Row({label}) {
3694
useEffect(() => {
packages/react-reconciler/src/__tests__/ReactIncremental-test.js
+10
-17
@@ -50,7 +50,6 @@ describe('ReactIncremental', () => {
50
expect(Scheduler).toFlushWithoutYielding();
51
});
52
53
- // @gate experimental || !enableSyncDefaultUpdates
53
it('should render a simple component, in steps if needed', () => {
54
function Bar() {
55
Scheduler.unstable_yieldValue('Bar');
@@ -67,7 +66,7 @@ describe('ReactIncremental', () => {
66
}
67
68
if (gate(flags => flags.enableSyncDefaultUpdates)) {
70
- React.unstable_startTransition(() => {
69
+ React.startTransition(() => {
70
ReactNoop.render(<Foo />, () =>
71
Scheduler.unstable_yieldValue('callback'),
72
);
@@ -143,7 +142,6 @@ describe('ReactIncremental', () => {
142
]);
143
});
144
146
- // @gate experimental || !enableSyncDefaultUpdates
145
it('can cancel partially rendered work and restart', () => {
146
function Bar(props) {
147
Scheduler.unstable_yieldValue('Bar');
@@ -165,7 +163,7 @@ describe('ReactIncremental', () => {
163
expect(Scheduler).toFlushAndYield(['Foo', 'Bar', 'Bar']);
164
165
if (gate(flags => flags.enableSyncDefaultUpdates)) {
168
- React.unstable_startTransition(() => {
166
+ React.startTransition(() => {
167
ReactNoop.render(<Foo text="bar" />);
168
});
169
} else {
@@ -178,7 +176,7 @@ describe('ReactIncremental', () => {
176
ReactNoop.flushSync(() => ReactNoop.render(null));
177
178
if (gate(flags => flags.enableSyncDefaultUpdates)) {
181
- React.unstable_startTransition(() => {
179
+ React.startTransition(() => {
180
ReactNoop.render(<Foo text="baz" />);
181
});
182
} else {
@@ -192,7 +190,6 @@ describe('ReactIncremental', () => {
190
expect(Scheduler).toFlushAndYield(['Bar']);
191
});
192
195
- // @gate experimental || !enableSyncDefaultUpdates
193
it('should call callbacks even if updates are aborted', () => {
194
let inst;
195
@@ -219,7 +216,7 @@ describe('ReactIncremental', () => {
216
expect(Scheduler).toFlushWithoutYielding();
217
218
if (gate(flags => flags.enableSyncDefaultUpdates)) {
222
- React.unstable_startTransition(() => {
219
+ React.startTransition(() => {
220
inst.setState(
221
() => {
222
Scheduler.unstable_yieldValue('setState1');
@@ -244,7 +241,7 @@ describe('ReactIncremental', () => {
241
// This will abort the previous work and restart
242
ReactNoop.flushSync(() => ReactNoop.render(<Foo />));
243
if (gate(flags => flags.enableSyncDefaultUpdates)) {
247
- React.unstable_startTransition(() => {
244
+ React.startTransition(() => {
245
inst.setState(
246
() => {
247
Scheduler.unstable_yieldValue('setState2');
@@ -1764,7 +1761,6 @@ describe('ReactIncremental', () => {
1761
expect(instance.state.n).toEqual(3);
1762
});
1763
1767
- // @gate experimental || !enableSyncDefaultUpdates
1764
it('merges and masks context', () => {
1765
class Intl extends React.Component {
1766
static childContextTypes = {
@@ -1883,7 +1879,7 @@ describe('ReactIncremental', () => {
1879
'ShowBoth {"locale":"de"}',
1880
]);
1881
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1886
- React.unstable_startTransition(() => {
1882
+ React.startTransition(() => {
1883
ReactNoop.render(
1884
<Intl locale="sv">
1885
<ShowLocale />
@@ -2033,7 +2029,7 @@ describe('ReactIncremental', () => {
2029
}
2030
2031
if (gate(flags => flags.enableSyncDefaultUpdates)) {
2036
- React.unstable_startTransition(() => {
2032
+ React.startTransition(() => {
2033
ReactNoop.render(
2034
<Intl locale="fr">
2035
<ShowLocale />
@@ -2739,7 +2735,6 @@ describe('ReactIncremental', () => {
2735
expect(Scheduler).toFlushAndYield(['count:1, name:not brian']);
2736
});
2737
2742
- // @gate experimental || !enableSyncDefaultUpdates
2738
it('does not interrupt for update at same priority', () => {
2739
function Parent(props) {
2740
Scheduler.unstable_yieldValue('Parent: ' + props.step);
@@ -2752,7 +2747,7 @@ describe('ReactIncremental', () => {
2747
}
2748
2749
if (gate(flags => flags.enableSyncDefaultUpdates)) {
2755
- React.unstable_startTransition(() => {
2750
+ React.startTransition(() => {
2751
ReactNoop.render(<Parent step={1} />);
2752
});
2753
} else {
@@ -2766,7 +2761,6 @@ describe('ReactIncremental', () => {
2761
expect(Scheduler).toFlushAndYield(['Child: 1', 'Parent: 2', 'Child: 2']);
2762
});
2763
2769
- // @gate experimental || !enableSyncDefaultUpdates
2764
it('does not interrupt for update at lower priority', () => {
2765
function Parent(props) {
2766
Scheduler.unstable_yieldValue('Parent: ' + props.step);
@@ -2779,7 +2773,7 @@ describe('ReactIncremental', () => {
2773
}
2774
2775
if (gate(flags => flags.enableSyncDefaultUpdates)) {
2782
- React.unstable_startTransition(() => {
2776
+ React.startTransition(() => {
2777
ReactNoop.render(<Parent step={1} />);
2778
});
2779
} else {
@@ -2794,7 +2788,6 @@ describe('ReactIncremental', () => {
2788
expect(Scheduler).toFlushAndYield(['Child: 1', 'Parent: 2', 'Child: 2']);
2789
});
2790
2797
- // @gate experimental || !enableSyncDefaultUpdates
2791
it('does interrupt for update at higher priority', () => {
2792
function Parent(props) {
2793
Scheduler.unstable_yieldValue('Parent: ' + props.step);
@@ -2807,7 +2800,7 @@ describe('ReactIncremental', () => {
2800
}
2801
2802
if (gate(flags => flags.enableSyncDefaultUpdates)) {
2810
- React.unstable_startTransition(() => {
2803
+ React.startTransition(() => {
2804
ReactNoop.render(<Parent step={1} />);
2805
});
2806
} else {
packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
+13
-22
@@ -58,7 +58,6 @@ describe('ReactIncrementalErrorHandling', () => {
58
);
59
}
60
61
- // @gate experimental || !enableSyncDefaultUpdates
61
it('recovers from errors asynchronously', () => {
62
class ErrorBoundary extends React.Component {
63
state = {error: null};
@@ -92,7 +91,7 @@ describe('ReactIncrementalErrorHandling', () => {
91
}
92
93
if (gate(flags => flags.enableSyncDefaultUpdates)) {
95
- React.unstable_startTransition(() => {
94
+ React.startTransition(() => {
95
ReactNoop.render(
96
<ErrorBoundary>
97
<Indirection>
@@ -171,7 +170,6 @@ describe('ReactIncrementalErrorHandling', () => {
170
expect(ReactNoop.getChildren()).toEqual([span('Caught an error: oops!')]);
171
});
172
174
- // @gate experimental || !enableSyncDefaultUpdates
173
it('recovers from errors asynchronously (legacy, no getDerivedStateFromError)', () => {
174
class ErrorBoundary extends React.Component {
175
state = {error: null};
@@ -205,7 +203,7 @@ describe('ReactIncrementalErrorHandling', () => {
203
}
204
205
if (gate(flags => flags.enableSyncDefaultUpdates)) {
208
- React.unstable_startTransition(() => {
206
+ React.startTransition(() => {
207
ReactNoop.render(
208
<ErrorBoundary>
209
<Indirection>
@@ -270,7 +268,6 @@ describe('ReactIncrementalErrorHandling', () => {
268
expect(ReactNoop.getChildren()).toEqual([span('Caught an error: oops!')]);
269
});
270
273
- // @gate experimental
271
it("retries at a lower priority if there's additional pending work", async () => {
272
function App(props) {
273
if (props.isBroken) {
@@ -285,12 +282,12 @@ describe('ReactIncrementalErrorHandling', () => {
282
Scheduler.unstable_yieldValue('commit');
283
}
284
288
- React.unstable_startTransition(() => {
285
+ React.startTransition(() => {
286
ReactNoop.render(<App isBroken={true} />, onCommit);
287
});
288
expect(Scheduler).toFlushAndYieldThrough(['error']);
289
293
- React.unstable_startTransition(() => {
290
+ React.startTransition(() => {
291
// This update is in a separate batch
292
ReactNoop.render(<App isBroken={false} />, onCommit);
293
});
@@ -333,14 +330,14 @@ describe('ReactIncrementalErrorHandling', () => {
330
Scheduler.unstable_yieldValue('commit');
331
}
332
336
- React.unstable_startTransition(() => {
333
+ React.startTransition(() => {
334
ReactNoop.render(<App isBroken={true} />, onCommit);
335
});
336
expect(Scheduler).toFlushAndYieldThrough(['error']);
337
338
expect(ReactNoop).toMatchRenderedOutput(null);
339
343
- React.unstable_startTransition(() => {
340
+ React.startTransition(() => {
341
// This update is in a separate batch
342
ReactNoop.render(<App isBroken={false} />, onCommit);
343
});
@@ -378,7 +375,6 @@ describe('ReactIncrementalErrorHandling', () => {
375
);
376
});
377
381
- // @gate experimental || !enableSyncDefaultUpdates
378
it('retries one more time before handling error', () => {
379
function BadRender({unused}) {
380
Scheduler.unstable_yieldValue('BadRender');
@@ -401,7 +397,7 @@ describe('ReactIncrementalErrorHandling', () => {
397
}
398
399
if (gate(flags => flags.enableSyncDefaultUpdates)) {
404
- React.unstable_startTransition(() => {
400
+ React.startTransition(() => {
401
ReactNoop.render(<Parent />, () =>
402
Scheduler.unstable_yieldValue('commit'),
403
);
@@ -429,7 +425,6 @@ describe('ReactIncrementalErrorHandling', () => {
425
expect(ReactNoop.getChildren()).toEqual([]);
426
});
427
432
- // @gate experimental || !enableSyncDefaultUpdates
428
it('retries one more time if an error occurs during a render that expires midway through the tree', async () => {
429
function Oops({unused}) {
430
Scheduler.unstable_yieldValue('Oops');
@@ -454,7 +449,7 @@ describe('ReactIncrementalErrorHandling', () => {
449
}
450
451
if (gate(flags => flags.enableSyncDefaultUpdates)) {
457
- React.unstable_startTransition(() => {
452
+ React.startTransition(() => {
453
ReactNoop.render(<App />);
454
});
455
} else {
@@ -566,7 +561,6 @@ describe('ReactIncrementalErrorHandling', () => {
561
expect(ReactNoop.getChildren()).toEqual([span('Caught an error: Hello.')]);
562
});
563
569
- // @gate experimental || !enableSyncDefaultUpdates
564
it('catches render error in a boundary during partial deferred mounting', () => {
565
class ErrorBoundary extends React.Component {
566
state = {error: null};
@@ -592,7 +586,7 @@ describe('ReactIncrementalErrorHandling', () => {
586
}
587
588
if (gate(flags => flags.enableSyncDefaultUpdates)) {
595
- React.unstable_startTransition(() => {
589
+ React.startTransition(() => {
590
ReactNoop.render(
591
<ErrorBoundary>
592
<BrokenRender />
@@ -757,7 +751,6 @@ describe('ReactIncrementalErrorHandling', () => {
751
expect(ReactNoop.getChildren()).toEqual([]);
752
});
753
760
- // @gate experimental || !enableSyncDefaultUpdates
754
it('propagates an error from a noop error boundary during partial deferred mounting', () => {
755
class RethrowErrorBoundary extends React.Component {
756
componentDidCatch(error) {
@@ -776,7 +769,7 @@ describe('ReactIncrementalErrorHandling', () => {
769
}
770
771
if (gate(flags => flags.enableSyncDefaultUpdates)) {
779
- React.unstable_startTransition(() => {
772
+ React.startTransition(() => {
773
ReactNoop.render(
774
<RethrowErrorBoundary>
775
<BrokenRender />
@@ -1842,7 +1835,6 @@ describe('ReactIncrementalErrorHandling', () => {
1835
});
1836
}
1837
1845
- // @gate experimental
1838
it('uncaught errors should be discarded if the render is aborted', async () => {
1839
const root = ReactNoop.createRoot();
1840
@@ -1853,7 +1845,7 @@ describe('ReactIncrementalErrorHandling', () => {
1845
1846
await ReactNoop.act(async () => {
1847
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1856
- React.unstable_startTransition(() => {
1848
+ React.startTransition(() => {
1849
root.render(<Oops />);
1850
});
1851
} else {
@@ -1866,7 +1858,7 @@ describe('ReactIncrementalErrorHandling', () => {
1858
// Interleaved update. When the root completes, instead of throwing the
1859
// error, it should try rendering again. This update will cause it to
1860
// recover gracefully.
1869
- React.unstable_startTransition(() => {
1861
+ React.startTransition(() => {
1862
root.render('Everything is fine.');
1863
});
1864
});
@@ -1875,7 +1867,6 @@ describe('ReactIncrementalErrorHandling', () => {
1867
expect(root).toMatchRenderedOutput('Everything is fine.');
1868
});
1869
1878
- // @gate experimental
1870
it('uncaught errors are discarded if the render is aborted, case 2', async () => {
1871
const {useState} = React;
1872
const root = ReactNoop.createRoot();
@@ -1902,7 +1893,7 @@ describe('ReactIncrementalErrorHandling', () => {
1893
await ReactNoop.act(async () => {
1894
// Schedule a default pri and a low pri update on the root.
1895
root.render(<Oops />);
1905
- React.unstable_startTransition(() => {
1896
+ React.startTransition(() => {
1897
root.render(<AllGood />);
1898
});
1899
packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.js
+5
-8
@@ -34,7 +34,6 @@ describe('ReactIncrementalReflection', () => {
34
return {type: 'span', children: [], prop, hidden: false};
35
}
36
37
- // @gate experimental || !enableSyncDefaultUpdates
37
it('handles isMounted even when the initial render is deferred', () => {
38
const instances = [];
39
@@ -65,7 +64,7 @@ describe('ReactIncrementalReflection', () => {
64
}
65
66
if (gate(flags => flags.enableSyncDefaultUpdates)) {
68
- React.unstable_startTransition(() => {
67
+ React.startTransition(() => {
68
ReactNoop.render(<Foo />);
69
});
70
} else {
@@ -83,7 +82,6 @@ describe('ReactIncrementalReflection', () => {
82
expect(instances[0]._isMounted()).toBe(true);
83
});
84
86
- // @gate experimental || !enableSyncDefaultUpdates
85
it('handles isMounted when an unmount is deferred', () => {
86
const instances = [];
87
@@ -120,7 +118,7 @@ describe('ReactIncrementalReflection', () => {
118
expect(instances[0]._isMounted()).toBe(true);
119
120
if (gate(flags => flags.enableSyncDefaultUpdates)) {
123
- React.unstable_startTransition(() => {
121
+ React.startTransition(() => {
122
ReactNoop.render(<Foo mount={false} />);
123
});
124
} else {
@@ -138,7 +136,6 @@ describe('ReactIncrementalReflection', () => {
136
expect(instances[0]._isMounted()).toBe(false);
137
});
138
141
- // @gate experimental || !enableSyncDefaultUpdates
139
it('finds no node before insertion and correct node before deletion', () => {
140
let classInstance = null;
141
@@ -210,7 +207,7 @@ describe('ReactIncrementalReflection', () => {
207
}
208
209
if (gate(flags => flags.enableSyncDefaultUpdates)) {
213
- React.unstable_startTransition(() => {
210
+ React.startTransition(() => {
211
ReactNoop.render(<Foo step={0} />);
212
});
213
} else {
@@ -250,7 +247,7 @@ describe('ReactIncrementalReflection', () => {
247
// The next step will render a new host node but won't get committed yet.
248
// We expect this to mutate the original Fiber.
249
if (gate(flags => flags.enableSyncDefaultUpdates)) {
253
- React.unstable_startTransition(() => {
250
+ React.startTransition(() => {
251
ReactNoop.render(<Foo step={2} />);
252
});
253
} else {
@@ -277,7 +274,7 @@ describe('ReactIncrementalReflection', () => {
274
275
// Render to null but don't commit it yet.
276
if (gate(flags => flags.enableSyncDefaultUpdates)) {
280
- React.unstable_startTransition(() => {
277
+ React.startTransition(() => {
278
ReactNoop.render(<Foo step={3} />);
279
});
280
} else {
packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js
+6
-10
@@ -85,7 +85,6 @@ describe('ReactIncrementalScheduling', () => {
85
expect(ReactNoop).toMatchRenderedOutput(<span prop={5} />);
86
});
87
88
- // @gate experimental || !enableSyncDefaultUpdates
88
it('works on deferred roots in the order they were scheduled', () => {
89
const {useEffect} = React;
90
function Text({text}) {
@@ -109,7 +108,7 @@ describe('ReactIncrementalScheduling', () => {
108
// Schedule deferred work in the reverse order
109
ReactNoop.act(() => {
110
if (gate(flags => flags.enableSyncDefaultUpdates)) {
112
- React.unstable_startTransition(() => {
111
+ React.startTransition(() => {
112
ReactNoop.renderToRootWithID(<Text text="c:2" />, 'c');
113
ReactNoop.renderToRootWithID(<Text text="b:2" />, 'b');
114
});
@@ -126,7 +125,7 @@ describe('ReactIncrementalScheduling', () => {
125
// Schedule last bit of work, it will get processed the last
126
127
if (gate(flags => flags.enableSyncDefaultUpdates)) {
129
- React.unstable_startTransition(() => {
128
+ React.startTransition(() => {
129
ReactNoop.renderToRootWithID(<Text text="a:2" />, 'a');
130
});
131
} else {
@@ -146,7 +145,6 @@ describe('ReactIncrementalScheduling', () => {
145
});
146
});
147
149
- // @gate experimental || !enableSyncDefaultUpdates
148
it('schedules sync updates when inside componentDidMount/Update', () => {
149
let instance;
150
@@ -186,7 +184,7 @@ describe('ReactIncrementalScheduling', () => {
184
}
185
186
if (gate(flags => flags.enableSyncDefaultUpdates)) {
189
- React.unstable_startTransition(() => {
187
+ React.startTransition(() => {
188
ReactNoop.render(<Foo />);
189
});
190
} else {
@@ -206,7 +204,7 @@ describe('ReactIncrementalScheduling', () => {
204
]);
205
206
if (gate(flags => flags.enableSyncDefaultUpdates)) {
209
- React.unstable_startTransition(() => {
207
+ React.startTransition(() => {
208
instance.setState({tick: 2});
209
});
210
} else {
@@ -224,7 +222,6 @@ describe('ReactIncrementalScheduling', () => {
222
]);
223
});
224
227
- // @gate experimental || !enableSyncDefaultUpdates
225
it('can opt-in to async scheduling inside componentDidMount/Update', () => {
226
let instance;
227
class Foo extends React.Component {
@@ -284,7 +281,7 @@ describe('ReactIncrementalScheduling', () => {
281
// Increment the tick to 2. This will trigger an update inside cDU. Flush
282
// the first update without flushing the second one.
283
if (gate(flags => flags.enableSyncDefaultUpdates)) {
287
- React.unstable_startTransition(() => {
284
+ React.startTransition(() => {
285
instance.setState({tick: 2});
286
});
287
@@ -315,7 +312,6 @@ describe('ReactIncrementalScheduling', () => {
312
}
313
});
314
318
- // @gate experimental || !enableSyncDefaultUpdates
315
it('performs Task work even after time runs out', () => {
316
class Foo extends React.Component {
317
state = {step: 1};
@@ -334,7 +330,7 @@ describe('ReactIncrementalScheduling', () => {
330
}
331
}
332
if (gate(flags => flags.enableSyncDefaultUpdates)) {
337
- React.unstable_startTransition(() => {
333
+ React.startTransition(() => {
334
ReactNoop.render(<Foo />);
335
});
336
} else {
packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js
+4
-6
@@ -384,7 +384,6 @@ describe('ReactIncrementalSideEffects', () => {
384
expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
385
});
386
387
- // @gate experimental || !enableSyncDefaultUpdates
387
it('does not update child nodes if a flush is aborted', () => {
388
function Bar(props) {
389
Scheduler.unstable_yieldValue('Bar');
@@ -411,7 +410,7 @@ describe('ReactIncrementalSideEffects', () => {
410
]);
411
412
if (gate(flags => flags.enableSyncDefaultUpdates)) {
414
- React.unstable_startTransition(() => {
413
+ React.startTransition(() => {
414
ReactNoop.render(<Foo text="World" />);
415
});
416
} else {
@@ -640,14 +639,13 @@ describe('ReactIncrementalSideEffects', () => {
639
);
640
});
641
643
- // @gate experimental || !enableSyncDefaultUpdates
642
it('can update a completed tree before it has a chance to commit', () => {
643
function Foo(props) {
644
Scheduler.unstable_yieldValue('Foo');
645
return <span prop={props.step} />;
646
}
647
if (gate(flags => flags.enableSyncDefaultUpdates)) {
650
- React.unstable_startTransition(() => {
648
+ React.startTransition(() => {
649
ReactNoop.render(<Foo step={1} />);
650
});
651
} else {
@@ -662,7 +660,7 @@ describe('ReactIncrementalSideEffects', () => {
660
expect(ReactNoop.getChildrenAsJSX()).toEqual(<span prop={1} />);
661
662
if (gate(flags => flags.enableSyncDefaultUpdates)) {
665
- React.unstable_startTransition(() => {
663
+ React.startTransition(() => {
664
ReactNoop.render(<Foo step={2} />);
665
});
666
} else {
@@ -675,7 +673,7 @@ describe('ReactIncrementalSideEffects', () => {
673
// new props
674
675
if (gate(flags => flags.enableSyncDefaultUpdates)) {
678
- React.unstable_startTransition(() => {
676
+ React.startTransition(() => {
677
ReactNoop.render(<Foo step={3} />);
678
});
679
} else {
packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js
+11
-18
@@ -131,7 +131,6 @@ describe('ReactIncrementalUpdates', () => {
131
expect(instance.state).toEqual({c: 'c', d: 'd'});
132
});
133
134
- // @gate experimental || !enableSyncDefaultUpdates
134
it('can abort an update, schedule additional updates, and resume', () => {
135
let instance;
136
class Foo extends React.Component {
@@ -162,7 +161,7 @@ describe('ReactIncrementalUpdates', () => {
161
162
// Schedule some async updates
163
if (gate(flags => flags.enableSyncDefaultUpdates)) {
165
- React.unstable_startTransition(() => {
164
+ React.startTransition(() => {
165
instance.setState(createUpdate('a'));
166
instance.setState(createUpdate('b'));
167
instance.setState(createUpdate('c'));
@@ -184,7 +183,7 @@ describe('ReactIncrementalUpdates', () => {
183
instance.setState(createUpdate('e'));
184
instance.setState(createUpdate('f'));
185
});
187
- React.unstable_startTransition(() => {
186
+ React.startTransition(() => {
187
instance.setState(createUpdate('g'));
188
});
189
@@ -229,7 +228,6 @@ describe('ReactIncrementalUpdates', () => {
228
}
229
});
230
232
- // @gate experimental || !enableSyncDefaultUpdates
231
it('can abort an update, schedule a replaceState, and resume', () => {
232
let instance;
233
class Foo extends React.Component {
@@ -260,7 +258,7 @@ describe('ReactIncrementalUpdates', () => {
258
259
// Schedule some async updates
260
if (gate(flags => flags.enableSyncDefaultUpdates)) {
263
- React.unstable_startTransition(() => {
261
+ React.startTransition(() => {
262
instance.setState(createUpdate('a'));
263
instance.setState(createUpdate('b'));
264
instance.setState(createUpdate('c'));
@@ -285,7 +283,7 @@ describe('ReactIncrementalUpdates', () => {
283
// reaching into the updater.
284
instance.updater.enqueueReplaceState(instance, createUpdate('f'));
285
});
288
- React.unstable_startTransition(() => {
286
+ React.startTransition(() => {
287
instance.setState(createUpdate('g'));
288
});
289
@@ -543,7 +541,6 @@ describe('ReactIncrementalUpdates', () => {
541
expect(ReactNoop.getChildren()).toEqual([span('derived state')]);
542
});
543
546
- // @gate experimental || !enableSyncDefaultUpdates
544
it('regression: does not expire soon due to layout effects in the last batch', () => {
545
const {useState, useLayoutEffect} = React;
546
@@ -561,7 +558,7 @@ describe('ReactIncrementalUpdates', () => {
558
559
ReactNoop.act(() => {
560
if (gate(flags => flags.enableSyncDefaultUpdates)) {
564
- React.unstable_startTransition(() => {
561
+ React.startTransition(() => {
562
ReactNoop.render(<App />);
563
});
564
} else {
@@ -577,7 +574,7 @@ describe('ReactIncrementalUpdates', () => {
574
575
Scheduler.unstable_advanceTime(10000);
576
if (gate(flags => flags.enableSyncDefaultUpdates)) {
580
- React.unstable_startTransition(() => {
577
+ React.startTransition(() => {
578
setCount(2);
579
});
580
} else {
@@ -588,7 +585,6 @@ describe('ReactIncrementalUpdates', () => {
585
});
586
});
587
591
- // @gate experimental || !enableSyncDefaultUpdates
588
it('regression: does not expire soon due to previous flushSync', () => {
589
function Text({text}) {
590
Scheduler.unstable_yieldValue(text);
@@ -603,7 +599,7 @@ describe('ReactIncrementalUpdates', () => {
599
Scheduler.unstable_advanceTime(10000);
600
601
if (gate(flags => flags.enableSyncDefaultUpdates)) {
606
- React.unstable_startTransition(() => {
602
+ React.startTransition(() => {
603
ReactNoop.render(<Text text="B" />);
604
});
605
} else {
@@ -613,7 +609,6 @@ describe('ReactIncrementalUpdates', () => {
609
expect(Scheduler).toHaveYielded([]);
610
});
611
616
- // @gate experimental || !enableSyncDefaultUpdates
612
it('regression: does not expire soon due to previous expired work', () => {
613
function Text({text}) {
614
Scheduler.unstable_yieldValue(text);
@@ -621,7 +616,7 @@ describe('ReactIncrementalUpdates', () => {
616
}
617
618
if (gate(flags => flags.enableSyncDefaultUpdates)) {
624
- React.unstable_startTransition(() => {
619
+ React.startTransition(() => {
620
ReactNoop.render(<Text text="A" />);
621
});
622
} else {
@@ -634,7 +629,7 @@ describe('ReactIncrementalUpdates', () => {
629
Scheduler.unstable_advanceTime(10000);
630
631
if (gate(flags => flags.enableSyncDefaultUpdates)) {
637
- React.unstable_startTransition(() => {
632
+ React.startTransition(() => {
633
ReactNoop.render(<Text text="B" />);
634
});
635
} else {
@@ -644,7 +639,6 @@ describe('ReactIncrementalUpdates', () => {
639
expect(Scheduler).toHaveYielded([]);
640
});
641
647
- // @gate experimental || !enableSyncDefaultUpdates
642
it('when rebasing, does not exclude updates that were already committed, regardless of priority', async () => {
643
const {useState, useLayoutEffect} = React;
644
@@ -678,7 +672,7 @@ describe('ReactIncrementalUpdates', () => {
672
673
await ReactNoop.act(async () => {
674
if (gate(flags => flags.enableSyncDefaultUpdates)) {
681
- React.unstable_startTransition(() => {
675
+ React.startTransition(() => {
676
pushToLog('A');
677
});
678
} else {
@@ -707,7 +701,6 @@ describe('ReactIncrementalUpdates', () => {
701
expect(root).toMatchRenderedOutput('ABCD');
702
});
703
710
- // @gate experimental || !enableSyncDefaultUpdates
704
it('when rebasing, does not exclude updates that were already committed, regardless of priority (classes)', async () => {
705
let pushToLog;
706
class App extends React.Component {
@@ -740,7 +733,7 @@ describe('ReactIncrementalUpdates', () => {
733
734
await ReactNoop.act(async () => {
735
if (gate(flags => flags.enableSyncDefaultUpdates)) {
743
- React.unstable_startTransition(() => {
736
+ React.startTransition(() => {
737
pushToLog('A');
738
});
739
} else {
packages/react-reconciler/src/__tests__/ReactInterleavedUpdates-test.js
+3
-5
@@ -12,7 +12,7 @@ describe('ReactInterleavedUpdates', () => {
12
React = require('react');
13
ReactNoop = require('react-noop-renderer');
14
Scheduler = require('scheduler');
15
- startTransition = React.unstable_startTransition;
15
+ startTransition = React.startTransition;
16
useState = React.useState;
17
useEffect = React.useEffect;
18
});
@@ -22,7 +22,6 @@ describe('ReactInterleavedUpdates', () => {
22
return text;
23
}
24
25
- // @gate experimental || !enableSyncDefaultUpdates
25
test('update during an interleaved event is not processed during the current render', async () => {
26
const updaters = [];
27
@@ -57,7 +56,7 @@ describe('ReactInterleavedUpdates', () => {
56
57
await ReactNoop.act(async () => {
58
if (gate(flags => flags.enableSyncDefaultUpdates)) {
60
- React.unstable_startTransition(() => {
59
+ React.startTransition(() => {
60
updateChildren(1);
61
});
62
} else {
@@ -69,7 +68,7 @@ describe('ReactInterleavedUpdates', () => {
68
// In an interleaved event, schedule an update on each of the children.
69
// Including the two that haven't rendered yet.
70
if (gate(flags => flags.enableSyncDefaultUpdates)) {
72
- React.unstable_startTransition(() => {
71
+ React.startTransition(() => {
72
updateChildren(2);
73
});
74
} else {
@@ -85,7 +84,6 @@ describe('ReactInterleavedUpdates', () => {
84
expect(root).toMatchRenderedOutput('222');
85
});
86
88
- // @gate experimental
87
// @gate !enableSyncDefaultUpdates
88
test('low priority update during an interleaved event is not processed during the current render', async () => {
89
// Same as previous test, but the interleaved update is lower priority than
packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js
+1
-2
@@ -1475,7 +1475,6 @@ describe('ReactLazy', () => {
1475
});
1476
1477
// @gate enableLazyElements
1478
- // @gate experimental || !enableSyncDefaultUpdates
1478
it('mount and reorder lazy elements', async () => {
1479
class Child extends React.Component {
1480
componentDidMount() {
@@ -1536,7 +1535,7 @@ describe('ReactLazy', () => {
1535
1536
// Swap the position of A and B
1537
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1539
- React.unstable_startTransition(() => {
1538
+ React.startTransition(() => {
1539
root.update(<Parent swap={true} />);
1540
});
1541
} else {
packages/react-reconciler/src/__tests__/ReactNewContext-test.js
+1
-2
@@ -828,7 +828,6 @@ describe('ReactNewContext', () => {
828
);
829
});
830
831
- // @gate experimental || !enableSyncDefaultUpdates
831
it('warns if multiple renderers concurrently render the same context', () => {
832
spyOnDev(console, 'error');
833
const Context = React.createContext(0);
@@ -848,7 +847,7 @@ describe('ReactNewContext', () => {
847
}
848
849
if (gate(flags => flags.enableSyncDefaultUpdates)) {
851
- React.unstable_startTransition(() => {
850
+ React.startTransition(() => {
851
ReactNoop.render(<App value={1} />);
852
});
853
} else {
packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js
+3
-5
@@ -28,7 +28,7 @@ describe('ReactSchedulerIntegration', () => {
28
NormalPriority = Scheduler.unstable_NormalPriority;
29
IdlePriority = Scheduler.unstable_IdlePriority;
30
runWithPriority = Scheduler.unstable_runWithPriority;
31
- startTransition = React.unstable_startTransition;
31
+ startTransition = React.startTransition;
32
});
33
34
// Note: This is based on a similar component we use in www. We can delete
@@ -88,7 +88,6 @@ describe('ReactSchedulerIntegration', () => {
88
]);
89
});
90
91
- // @gate experimental || !enableSyncDefaultUpdates
91
it('requests a paint after committing', () => {
92
const scheduleCallback = Scheduler.unstable_scheduleCallback;
93
@@ -102,7 +101,7 @@ describe('ReactSchedulerIntegration', () => {
101
102
// Schedule a React render. React will request a paint after committing it.
103
if (gate(flags => flags.enableSyncDefaultUpdates)) {
105
- React.unstable_startTransition(() => {
104
+ React.startTransition(() => {
105
root.render('Update');
106
});
107
} else {
@@ -203,7 +202,7 @@ describe(
202
React = require('react');
203
ReactNoop = require('react-noop-renderer');
204
Scheduler = require('scheduler');
206
- startTransition = React.unstable_startTransition;
205
+ startTransition = React.startTransition;
206
});
207
208
afterEach(() => {
@@ -252,7 +251,6 @@ describe(
251
});
252
});
253
255
- // @gate experimental
254
it('mock Scheduler module to check if `shouldYield` is called', async () => {
255
// This test reproduces a bug where React's Scheduler task timed out but
256
// the `shouldYield` method returned true. Usually we try not to mock
packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js
+3
-6
@@ -96,7 +96,6 @@ describe('ReactSuspense', () => {
96
}
97
}
98
99
- // @gate experimental || !enableSyncDefaultUpdates
99
it('suspends rendering and continues later', () => {
100
function Bar(props) {
101
Scheduler.unstable_yieldValue('Bar');
@@ -128,7 +127,7 @@ describe('ReactSuspense', () => {
127
// Navigate the shell to now render the child content.
128
// This should suspend.
129
if (gate(flags => flags.enableSyncDefaultUpdates)) {
131
- React.unstable_startTransition(() => {
130
+ React.startTransition(() => {
131
root.update(<Foo renderBar={true} />);
132
});
133
} else {
@@ -201,7 +200,6 @@ describe('ReactSuspense', () => {
200
expect(root).toMatchRenderedOutput('AB');
201
});
202
204
- // @gate experimental || !enableSyncDefaultUpdates
203
it('interrupts current render if promise resolves before current render phase', () => {
204
let didResolve = false;
205
const listeners = [];
@@ -244,7 +242,7 @@ describe('ReactSuspense', () => {
242
243
// The update will suspend.
244
if (gate(flags => flags.enableSyncDefaultUpdates)) {
247
- React.unstable_startTransition(() => {
245
+ React.startTransition(() => {
246
root.update(
247
<>
248
<Suspense fallback={<Text text="Loading..." />}>
@@ -289,7 +287,6 @@ describe('ReactSuspense', () => {
287
expect(root).toMatchRenderedOutput('AsyncAfter SuspenseSibling');
288
});
289
292
- // @gate experimental
290
// @gate !enableSyncDefaultUpdates
291
it(
292
'interrupts current render when something suspends with a ' +
@@ -331,7 +328,7 @@ describe('ReactSuspense', () => {
328
329
// Schedule another update. This will have lower priority because it's
330
// a transition.
334
- React.unstable_startTransition(() => {
331
+ React.startTransition(() => {
332
root.update(<App shouldSuspend={false} step={2} />);
333
});
334
packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js
+7
-44
@@ -14,7 +14,7 @@ describe('ReactSuspenseList', () => {
14
Scheduler = require('scheduler');
15
Profiler = React.Profiler;
16
Suspense = React.Suspense;
17
- SuspenseList = React.unstable_SuspenseList;
17
+ SuspenseList = React.SuspenseList;
18
});
19
20
function Text(props) {
@@ -40,7 +40,6 @@ describe('ReactSuspenseList', () => {
40
return Component;
41
}
42
43
- // @gate experimental
43
it('warns if an unsupported revealOrder option is used', () => {
44
function Foo() {
45
return (
@@ -60,7 +59,6 @@ describe('ReactSuspenseList', () => {
59
]);
60
});
61
63
- // @gate experimental
62
it('warns if a upper case revealOrder option is used', () => {
63
function Foo() {
64
return (
@@ -80,7 +78,6 @@ describe('ReactSuspenseList', () => {
78
]);
79
});
80
83
- // @gate experimental
81
it('warns if a misspelled revealOrder option is used', () => {
82
function Foo() {
83
return (
@@ -101,7 +98,6 @@ describe('ReactSuspenseList', () => {
98
]);
99
});
100
104
- // @gate experimental
101
it('warns if a single element is passed to a "forwards" list', () => {
102
function Foo({children}) {
103
return <SuspenseList revealOrder="forwards">{children}</SuspenseList>;
@@ -134,7 +130,6 @@ describe('ReactSuspenseList', () => {
130
]);
131
});
132
137
- // @gate experimental
133
it('warns if a single fragment is passed to a "backwards" list', () => {
134
function Foo() {
135
return (
@@ -155,7 +150,6 @@ describe('ReactSuspenseList', () => {
150
]);
151
});
152
158
- // @gate experimental
153
it('warns if a nested array is passed to a "forwards" list', () => {
154
function Foo({items}) {
155
return (
@@ -183,7 +177,6 @@ describe('ReactSuspenseList', () => {
177
]);
178
});
179
186
- // @gate experimental
180
it('shows content independently by default', async () => {
181
const A = createAsyncText('A');
182
const B = createAsyncText('B');
@@ -250,7 +243,6 @@ describe('ReactSuspenseList', () => {
243
);
244
});
245
253
- // @gate experimental
246
it('shows content independently in legacy mode regardless of option', async () => {
247
const A = createAsyncText('A');
248
const B = createAsyncText('B');
@@ -321,7 +313,6 @@ describe('ReactSuspenseList', () => {
313
);
314
});
315
324
- // @gate experimental
316
it('displays all "together"', async () => {
317
const A = createAsyncText('A');
318
const B = createAsyncText('B');
@@ -391,7 +382,6 @@ describe('ReactSuspenseList', () => {
382
);
383
});
384
394
- // @gate experimental
385
it('displays all "together" even when nested as siblings', async () => {
386
const A = createAsyncText('A');
387
const B = createAsyncText('B');
@@ -477,7 +467,6 @@ describe('ReactSuspenseList', () => {
467
);
468
});
469
480
- // @gate experimental
470
it('displays all "together" in nested SuspenseLists', async () => {
471
const A = createAsyncText('A');
472
const B = createAsyncText('B');
@@ -539,7 +528,6 @@ describe('ReactSuspenseList', () => {
528
);
529
});
530
542
- // @gate experimental
531
it('displays all "together" in nested SuspenseLists where the inner is default', async () => {
532
const A = createAsyncText('A');
533
const B = createAsyncText('B');
@@ -599,7 +587,6 @@ describe('ReactSuspenseList', () => {
587
);
588
});
589
602
- // @gate experimental
590
it('displays all "together" during an update', async () => {
591
const A = createAsyncText('A');
592
const B = createAsyncText('B');
@@ -684,7 +671,6 @@ describe('ReactSuspenseList', () => {
671
);
672
});
673
687
- // @gate experimental
674
it('avoided boundaries can be coordinate with SuspenseList', async () => {
675
const A = createAsyncText('A');
676
const B = createAsyncText('B');
@@ -783,7 +769,6 @@ describe('ReactSuspenseList', () => {
769
);
770
});
771
786
- // @gate experimental
772
it('displays each items in "forwards" order', async () => {
773
const A = createAsyncText('A');
774
const B = createAsyncText('B');
@@ -849,7 +834,6 @@ describe('ReactSuspenseList', () => {
834
);
835
});
836
852
- // @gate experimental
837
it('displays each items in "backwards" order', async () => {
838
const A = createAsyncText('A');
839
const B = createAsyncText('B');
@@ -915,7 +899,6 @@ describe('ReactSuspenseList', () => {
899
);
900
});
901
918
- // @gate experimental
902
it('displays added row at the top "together" and the bottom in "forwards" order', async () => {
903
const A = createAsyncText('A');
904
const B = createAsyncText('B');
@@ -1070,7 +1053,6 @@ describe('ReactSuspenseList', () => {
1053
);
1054
});
1055
1073
- // @gate experimental
1056
it('displays added row at the top "together" and the bottom in "backwards" order', async () => {
1057
const A = createAsyncText('A');
1058
const B = createAsyncText('B');
@@ -1255,7 +1237,6 @@ describe('ReactSuspenseList', () => {
1237
);
1238
});
1239
1258
- // @gate experimental
1240
it('switches to rendering fallbacks if the tail takes long CPU time', async () => {
1241
function Foo() {
1242
return (
@@ -1275,7 +1256,7 @@ describe('ReactSuspenseList', () => {
1256
1257
// This render is only CPU bound. Nothing suspends.
1258
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1278
- React.unstable_startTransition(() => {
1259
+ React.startTransition(() => {
1260
ReactNoop.render(<Foo />);
1261
});
1262
} else {
@@ -1324,7 +1305,6 @@ describe('ReactSuspenseList', () => {
1305
);
1306
});
1307
1327
- // @gate experimental
1308
it('only shows one loading state at a time for "collapsed" tail insertions', async () => {
1309
const A = createAsyncText('A');
1310
const B = createAsyncText('B');
@@ -1394,7 +1374,6 @@ describe('ReactSuspenseList', () => {
1374
);
1375
});
1376
1397
- // @gate experimental
1377
it('warns if an unsupported tail option is used', () => {
1378
function Foo() {
1379
return (
@@ -1415,7 +1394,6 @@ describe('ReactSuspenseList', () => {
1394
]);
1395
});
1396
1418
- // @gate experimental
1397
it('warns if a tail option is used with "together"', () => {
1398
function Foo() {
1399
return (
@@ -1436,7 +1414,6 @@ describe('ReactSuspenseList', () => {
1414
]);
1415
});
1416
1439
- // @gate experimental
1417
it('renders one "collapsed" fallback even if CPU time elapsed', async () => {
1418
function Foo() {
1419
return (
@@ -1459,7 +1436,7 @@ describe('ReactSuspenseList', () => {
1436
1437
// This render is only CPU bound. Nothing suspends.
1438
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1462
- React.unstable_startTransition(() => {
1439
+ React.startTransition(() => {
1440
ReactNoop.render(<Foo />);
1441
});
1442
} else {
@@ -1509,7 +1486,6 @@ describe('ReactSuspenseList', () => {
1486
);
1487
});
1488
1512
- // @gate experimental
1489
it('adding to the middle does not collapse insertions (forwards)', async () => {
1490
const A = createAsyncText('A');
1491
const B = createAsyncText('B');
@@ -1652,7 +1628,6 @@ describe('ReactSuspenseList', () => {
1628
);
1629
});
1630
1655
- // @gate experimental
1631
it('adding to the middle does not collapse insertions (backwards)', async () => {
1632
const A = createAsyncText('A');
1633
const B = createAsyncText('B');
@@ -1800,7 +1775,6 @@ describe('ReactSuspenseList', () => {
1775
);
1776
});
1777
1803
- // @gate experimental
1778
it('adding to the middle of committed tail does not collapse insertions', async () => {
1779
const A = createAsyncText('A');
1780
const B = createAsyncText('B');
@@ -1958,7 +1932,6 @@ describe('ReactSuspenseList', () => {
1932
);
1933
});
1934
1961
- // @gate experimental
1935
it('only shows no initial loading state "hidden" tail insertions', async () => {
1936
const A = createAsyncText('A');
1937
const B = createAsyncText('B');
@@ -2022,7 +1995,6 @@ describe('ReactSuspenseList', () => {
1995
);
1996
});
1997
2025
- // @gate experimental
1998
it('eventually resolves a nested forwards suspense list', async () => {
1999
const B = createAsyncText('B');
2000
@@ -2085,7 +2057,6 @@ describe('ReactSuspenseList', () => {
2057
);
2058
});
2059
2088
- // @gate experimental
2060
it('eventually resolves a nested forwards suspense list with a hidden tail', async () => {
2061
const B = createAsyncText('B');
2062
@@ -2132,7 +2103,6 @@ describe('ReactSuspenseList', () => {
2103
);
2104
});
2105
2135
- // @gate experimental
2106
it('eventually resolves two nested forwards suspense lists with a hidden tail', async () => {
2107
const B = createAsyncText('B');
2108
@@ -2200,7 +2170,6 @@ describe('ReactSuspenseList', () => {
2170
);
2171
});
2172
2203
- // @gate experimental
2173
it('can do unrelated adjacent updates', async () => {
2174
let updateAdjacent;
2175
function Adjacent() {
@@ -2247,7 +2216,6 @@ describe('ReactSuspenseList', () => {
2216
);
2217
});
2218
2250
- // @gate experimental
2219
it('is able to re-suspend the last rows during an update with hidden', async () => {
2220
const AsyncB = createAsyncText('B');
2221
@@ -2336,7 +2304,6 @@ describe('ReactSuspenseList', () => {
2304
expect(previousInst).toBe(setAsyncB);
2305
});
2306
2339
- // @gate experimental
2307
it('is able to re-suspend the last rows during an update with hidden', async () => {
2308
const AsyncB = createAsyncText('B');
2309
@@ -2425,7 +2392,6 @@ describe('ReactSuspenseList', () => {
2392
expect(previousInst).toBe(setAsyncB);
2393
});
2394
2428
- // @gate experimental
2395
it('is able to interrupt a partially rendered tree and continue later', async () => {
2396
const AsyncA = createAsyncText('A');
2397
@@ -2462,7 +2428,7 @@ describe('ReactSuspenseList', () => {
2428
await ReactNoop.act(async () => {
2429
// Add a few items at the end.
2430
if (gate(flags => flags.enableSyncDefaultUpdates)) {
2465
- React.unstable_startTransition(() => {
2431
+ React.startTransition(() => {
2432
updateLowPri(true);
2433
});
2434
} else {
@@ -2504,7 +2470,6 @@ describe('ReactSuspenseList', () => {
2470
);
2471
});
2472
2507
- // @gate experimental
2473
it('can resume class components when revealed together', async () => {
2474
const A = createAsyncText('A');
2475
const B = createAsyncText('B');
@@ -2567,7 +2532,6 @@ describe('ReactSuspenseList', () => {
2532
);
2533
});
2534
2570
- // @gate experimental
2535
it('should be able to progressively show CPU expensive rows with two pass rendering', async () => {
2536
function TwoPass({text}) {
2537
const [pass, setPass] = React.useState(0);
@@ -2605,7 +2569,7 @@ describe('ReactSuspenseList', () => {
2569
}
2570
2571
if (gate(flags => flags.enableSyncDefaultUpdates)) {
2608
- React.unstable_startTransition(() => {
2572
+ React.startTransition(() => {
2573
ReactNoop.render(<App />);
2574
});
2575
} else {
@@ -2638,7 +2602,6 @@ describe('ReactSuspenseList', () => {
2602
);
2603
});
2604
2641
- // @gate experimental
2605
it('should be able to progressively show rows with two pass rendering and visible', async () => {
2606
function TwoPass({text}) {
2607
const [pass, setPass] = React.useState(0);
@@ -2678,7 +2641,7 @@ describe('ReactSuspenseList', () => {
2641
}
2642
2643
if (gate(flags => flags.enableSyncDefaultUpdates)) {
2681
- React.unstable_startTransition(() => {
2644
+ React.startTransition(() => {
2645
ReactNoop.render(<App />);
2646
});
2647
} else {
@@ -2720,7 +2683,7 @@ describe('ReactSuspenseList', () => {
2683
);
2684
});
2685
2723
- // @gate experimental && enableProfilerTimer
2686
+ // @gate enableProfilerTimer
2687
it('counts the actual duration when profiling a SuspenseList', async () => {
2688
// Order of parameters: id, phase, actualDuration, treeBaseDuration
2689
const onRender = jest.fn();
packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
+44
-61
@@ -212,7 +212,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
212
}
213
214
if (gate(flags => flags.enableSyncDefaultUpdates)) {
215
- React.unstable_startTransition(() => {
215
+ React.startTransition(() => {
216
ReactNoop.render(<Foo />);
217
});
218
} else {
@@ -284,7 +284,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
284
285
// The update will suspend.
286
if (gate(flags => flags.enableSyncDefaultUpdates)) {
287
- React.unstable_startTransition(() => {
287
+ React.startTransition(() => {
288
ReactNoop.render(<Foo renderBar={true} />);
289
});
290
} else {
@@ -354,7 +354,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
354
expect(Scheduler).toFlushAndYield([]);
355
// B suspends. Continue rendering the remaining siblings.
356
if (gate(flags => flags.enableSyncDefaultUpdates)) {
357
- React.unstable_startTransition(() => {
357
+ React.startTransition(() => {
358
ReactNoop.render(
359
<Suspense fallback={<Text text="Loading..." />}>
360
<Text text="A" />
@@ -401,7 +401,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
401
// TODO: Delete this feature flag.
402
// @gate !replayFailedUnitOfWorkWithInvokeGuardedCallback || !__DEV__
403
// @gate enableCache
404
- // @gate experimental || !enableSyncDefaultUpdates
404
it('retries on error', async () => {
405
class ErrorBoundary extends React.Component {
406
state = {error: null};
@@ -437,7 +436,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
436
expect(ReactNoop.getChildren()).toEqual([]);
437
438
if (gate(flags => flags.enableSyncDefaultUpdates)) {
440
- React.unstable_startTransition(() => {
439
+ React.startTransition(() => {
440
ReactNoop.render(<App renderContent={true} />);
441
});
442
} else {
@@ -567,7 +566,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
566
});
567
568
// @gate enableCache
570
- // @gate experimental || !enableSyncDefaultUpdates
569
it('keeps working on lower priority work after being pinged', async () => {
570
// Advance the virtual time so that we're close to the edge of a bucket.
571
ReactNoop.expire(149);
@@ -586,7 +584,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
584
expect(ReactNoop.getChildren()).toEqual([]);
585
586
if (gate(flags => flags.enableSyncDefaultUpdates)) {
589
- React.unstable_startTransition(() => {
587
+ React.startTransition(() => {
588
ReactNoop.render(<App showA={true} showB={false} />);
589
});
590
} else {
@@ -599,7 +597,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
597
// but not enough to expire the suspense timeout.
598
ReactNoop.expire(120);
599
if (gate(flags => flags.enableSyncDefaultUpdates)) {
602
- React.unstable_startTransition(() => {
600
+ React.startTransition(() => {
601
ReactNoop.render(<App showA={true} showB={true} />);
602
});
603
} else {
@@ -630,7 +628,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
628
// Default pri
629
ReactNoop.render(<App />);
630
// Low pri
633
- React.unstable_startTransition(() => {
631
+ React.startTransition(() => {
632
ReactNoop.render(<App hide={true} />);
633
});
634
@@ -647,7 +645,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
645
// times model. Might not make sense in the new model.
646
// TODO: This test doesn't over what it was originally designed to test.
647
// Either rewrite or delete.
650
- // @gate experimental || !enableSyncDefaultUpdates
648
it('tries each subsequent level after suspending', async () => {
649
const root = ReactNoop.createRoot();
650
@@ -683,7 +680,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
680
// Schedule an update at several distinct expiration times
681
await ReactNoop.act(async () => {
682
if (gate(flags => flags.enableSyncDefaultUpdates)) {
686
- React.unstable_startTransition(() => {
683
+ React.startTransition(() => {
684
root.render(<App step={1} shouldSuspend={true} />);
685
});
686
} else {
@@ -694,7 +691,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
691
interrupt();
692
693
if (gate(flags => flags.enableSyncDefaultUpdates)) {
697
- React.unstable_startTransition(() => {
694
+ React.startTransition(() => {
695
root.render(<App step={2} shouldSuspend={true} />);
696
});
697
} else {
@@ -705,7 +702,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
702
interrupt();
703
704
if (gate(flags => flags.enableSyncDefaultUpdates)) {
708
- React.unstable_startTransition(() => {
705
+ React.startTransition(() => {
706
root.render(<App step={3} shouldSuspend={true} />);
707
});
708
} else {
@@ -928,7 +925,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
925
expect(ReactNoop.getChildren()).toEqual([span('Async'), span('Sync')]);
926
});
927
931
- // @gate experimental
928
+ // @gate enableCache
929
it('does not expire for transitions', async () => {
930
ReactNoop.render(
931
<Fragment>
@@ -937,7 +934,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
934
);
935
expect(Scheduler).toFlushAndYield([]);
936
940
- React.unstable_startTransition(() => {
937
+ React.startTransition(() => {
938
ReactNoop.render(
939
<Fragment>
940
<Suspense fallback={<Text text="Loading..." />}>
@@ -984,7 +981,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
981
expect(Scheduler).toFlushAndYield([]);
982
expect(ReactNoop.getChildren()).toEqual([]);
983
if (gate(flags => flags.enableSyncDefaultUpdates)) {
987
- React.unstable_startTransition(() => {
984
+ React.startTransition(() => {
985
ReactNoop.render(
986
<>
987
<Suspense fallback={<Text text="Loading..." />}>
@@ -1051,7 +1048,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1048
expect(Scheduler).toFlushAndYield([]);
1049
1050
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1054
- React.unstable_startTransition(() => {
1051
+ React.startTransition(() => {
1052
ReactNoop.render(
1053
<Suspense fallback={<Text text="Loading..." />}>
1054
<AsyncText text="Async" />
@@ -1075,7 +1072,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1072
expect(ReactNoop.getChildren()).toEqual([span('Async')]);
1073
});
1074
1078
- // @gate experimental
1075
// @gate enableCache
1076
it('starts working on an update even if its priority falls between two suspended levels', async () => {
1077
function App(props) {
@@ -1096,7 +1092,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1092
expect(Scheduler).toFlushAndYield(['S']);
1093
1094
// Schedule an update, and suspend for up to 5 seconds.
1099
- React.unstable_startTransition(() => ReactNoop.render(<App text="A" />));
1095
+ React.startTransition(() => ReactNoop.render(<App text="A" />));
1096
// The update should suspend.
1097
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
1098
expect(ReactNoop.getChildren()).toEqual([span('S')]);
@@ -1108,7 +1104,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1104
expect(ReactNoop.getChildren()).toEqual([span('S')]);
1105
1106
// Schedule another low priority update.
1111
- React.unstable_startTransition(() => ReactNoop.render(<App text="B" />));
1107
+ React.startTransition(() => ReactNoop.render(<App text="B" />));
1108
// This update should also suspend.
1109
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
1110
expect(ReactNoop.getChildren()).toEqual([span('S')]);
@@ -1857,7 +1853,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1853
});
1854
1855
// @gate enableCache
1860
- // @gate experimental || !enableSyncDefaultUpdates
1856
it('suspends for longer if something took a long (CPU bound) time to render', async () => {
1857
function Foo({renderContent}) {
1858
Scheduler.unstable_yieldValue('Foo');
@@ -1872,7 +1867,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1867
expect(Scheduler).toFlushAndYield(['Foo']);
1868
1869
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1875
- React.unstable_startTransition(() => {
1870
+ React.startTransition(() => {
1871
ReactNoop.render(<Foo renderContent={true} />);
1872
});
1873
} else {
@@ -2044,7 +2039,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2039
expect(Scheduler).toFlushAndYield(['Foo']);
2040
2041
if (gate(flags => flags.enableSyncDefaultUpdates)) {
2047
- React.unstable_startTransition(() => {
2042
+ React.startTransition(() => {
2043
ReactNoop.render(<Foo renderContent={true} />);
2044
});
2045
} else {
@@ -2365,7 +2360,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2360
expect(ReactNoop.getChildren()).toEqual([span('A')]);
2361
2362
if (gate(flags => flags.enableSyncDefaultUpdates)) {
2368
- React.unstable_startTransition(() => {
2363
+ React.startTransition(() => {
2364
ReactNoop.render(<Foo showB={true} />);
2365
});
2366
} else {
@@ -2445,7 +2440,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2440
});
2441
2442
describe('startTransition', () => {
2448
- // @gate experimental
2443
// @gate enableCache
2444
it('top level render', async () => {
2445
function App({page}) {
@@ -2457,7 +2451,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2451
}
2452
2453
// Initial render.
2460
- React.unstable_startTransition(() => ReactNoop.render(<App page="A" />));
2454
+ React.startTransition(() => ReactNoop.render(<App page="A" />));
2455
2456
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
2457
// Only a short time is needed to unsuspend the initial loading state.
@@ -2471,7 +2465,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2465
expect(ReactNoop.getChildren()).toEqual([span('A')]);
2466
2467
// Start transition.
2474
- React.unstable_startTransition(() => ReactNoop.render(<App page="B" />));
2468
+ React.startTransition(() => ReactNoop.render(<App page="B" />));
2469
2470
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
2471
Scheduler.unstable_advanceTime(100000);
@@ -2485,7 +2479,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2479
expect(ReactNoop.getChildren()).toEqual([span('B')]);
2480
});
2481
2488
- // @gate experimental
2482
// @gate enableCache
2483
it('hooks', async () => {
2484
let transitionToPage;
@@ -2507,7 +2500,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2500
2501
// Initial render.
2502
await ReactNoop.act(async () => {
2510
- React.unstable_startTransition(() => transitionToPage('A'));
2503
+ React.startTransition(() => transitionToPage('A'));
2504
2505
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
2506
// Only a short time is needed to unsuspend the initial loading state.
@@ -2523,7 +2516,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2516
2517
// Start transition.
2518
await ReactNoop.act(async () => {
2526
- React.unstable_startTransition(() => transitionToPage('B'));
2519
+ React.startTransition(() => transitionToPage('B'));
2520
2521
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
2522
Scheduler.unstable_advanceTime(100000);
@@ -2538,7 +2531,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2531
expect(ReactNoop.getChildren()).toEqual([span('B')]);
2532
});
2533
2541
- // @gate experimental
2534
// @gate enableCache
2535
it('classes', async () => {
2536
let transitionToPage;
@@ -2563,7 +2555,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2555
2556
// Initial render.
2557
await ReactNoop.act(async () => {
2566
- React.unstable_startTransition(() => transitionToPage('A'));
2558
+ React.startTransition(() => transitionToPage('A'));
2559
2560
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
2561
// Only a short time is needed to unsuspend the initial loading state.
@@ -2579,7 +2571,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2571
2572
// Start transition.
2573
await ReactNoop.act(async () => {
2582
- React.unstable_startTransition(() => transitionToPage('B'));
2574
+ React.startTransition(() => transitionToPage('B'));
2575
2576
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
2577
Scheduler.unstable_advanceTime(100000);
@@ -2596,7 +2588,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2588
});
2589
2590
describe('delays transitions when using React.startTranistion', () => {
2599
- // @gate experimental
2591
// @gate enableCache
2592
it('top level render', async () => {
2593
function App({page}) {
@@ -2608,7 +2599,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2599
}
2600
2601
// Initial render.
2611
- React.unstable_startTransition(() => ReactNoop.render(<App page="A" />));
2602
+ React.startTransition(() => ReactNoop.render(<App page="A" />));
2603
2604
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
2605
// Only a short time is needed to unsuspend the initial loading state.
@@ -2622,7 +2613,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2613
expect(ReactNoop.getChildren()).toEqual([span('A')]);
2614
2615
// Start transition.
2625
- React.unstable_startTransition(() => ReactNoop.render(<App page="B" />));
2616
+ React.startTransition(() => ReactNoop.render(<App page="B" />));
2617
2618
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
2619
Scheduler.unstable_advanceTime(2999);
@@ -2637,7 +2628,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2628
expect(ReactNoop.getChildren()).toEqual([span('B')]);
2629
2630
// Start a long (infinite) transition.
2640
- React.unstable_startTransition(() => ReactNoop.render(<App page="C" />));
2631
+ React.startTransition(() => ReactNoop.render(<App page="C" />));
2632
expect(Scheduler).toFlushAndYield(['Suspend! [C]', 'Loading...']);
2633
2634
// Even after lots of time has passed, we have still not yet flushed the
@@ -2647,7 +2638,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2638
expect(ReactNoop.getChildren()).toEqual([span('B')]);
2639
});
2640
2650
- // @gate experimental
2641
// @gate enableCache
2642
it('hooks', async () => {
2643
let transitionToPage;
@@ -2669,7 +2659,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2659
2660
// Initial render.
2661
await ReactNoop.act(async () => {
2672
- React.unstable_startTransition(() => transitionToPage('A'));
2662
+ React.startTransition(() => transitionToPage('A'));
2663
2664
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
2665
// Only a short time is needed to unsuspend the initial loading state.
@@ -2685,7 +2675,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2675
2676
// Start transition.
2677
await ReactNoop.act(async () => {
2688
- React.unstable_startTransition(() => transitionToPage('B'));
2678
+ React.startTransition(() => transitionToPage('B'));
2679
2680
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
2681
@@ -2703,7 +2693,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2693
2694
// Start a long (infinite) transition.
2695
await ReactNoop.act(async () => {
2706
- React.unstable_startTransition(() => transitionToPage('C'));
2696
+ React.startTransition(() => transitionToPage('C'));
2697
2698
expect(Scheduler).toFlushAndYield(['Suspend! [C]', 'Loading...']);
2699
@@ -2715,7 +2705,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2705
});
2706
});
2707
2718
- // @gate experimental
2708
// @gate enableCache
2709
it('classes', async () => {
2710
let transitionToPage;
@@ -2740,7 +2729,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2729
2730
// Initial render.
2731
await ReactNoop.act(async () => {
2743
- React.unstable_startTransition(() => transitionToPage('A'));
2732
+ React.startTransition(() => transitionToPage('A'));
2733
2734
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
2735
// Only a short time is needed to unsuspend the initial loading state.
@@ -2756,7 +2745,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2745
2746
// Start transition.
2747
await ReactNoop.act(async () => {
2759
- React.unstable_startTransition(() => transitionToPage('B'));
2748
+ React.startTransition(() => transitionToPage('B'));
2749
2750
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
2751
Scheduler.unstable_advanceTime(2999);
@@ -2773,7 +2762,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2762
2763
// Start a long (infinite) transition.
2764
await ReactNoop.act(async () => {
2776
- React.unstable_startTransition(() => transitionToPage('C'));
2765
+ React.startTransition(() => transitionToPage('C'));
2766
2767
expect(Scheduler).toFlushAndYield(['Suspend! [C]', 'Loading...']);
2768
@@ -2786,7 +2775,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2775
});
2776
});
2777
2789
- // @gate experimental
2778
// @gate enableCache
2779
it('do not show placeholder when updating an avoided boundary with startTransition', async () => {
2780
function App({page}) {
@@ -2810,7 +2798,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2798
expect(ReactNoop.getChildren()).toEqual([span('Hi!'), span('A')]);
2799
2800
// Start transition.
2813
- React.unstable_startTransition(() => ReactNoop.render(<App page="B" />));
2801
+ React.startTransition(() => ReactNoop.render(<App page="B" />));
2802
2803
expect(Scheduler).toFlushAndYield(['Hi!', 'Suspend! [B]', 'Loading B...']);
2804
@@ -2831,7 +2819,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2819
);
2820
});
2821
2834
- // @gate experimental
2822
// @gate enableCache
2823
it('do not show placeholder when mounting an avoided boundary with startTransition', async () => {
2824
function App({page}) {
@@ -2857,7 +2844,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2844
expect(ReactNoop.getChildren()).toEqual([span('Hi!'), span('A')]);
2845
2846
// Start transition.
2860
- React.unstable_startTransition(() => ReactNoop.render(<App page="B" />));
2847
+ React.startTransition(() => ReactNoop.render(<App page="B" />));
2848
2849
expect(Scheduler).toFlushAndYield(['Hi!', 'Suspend! [B]', 'Loading B...']);
2850
@@ -2913,7 +2900,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2900
// Update. Since showing a fallback would hide content that's already
2901
// visible, it should suspend for a JND without committing.
2902
if (gate(flags => flags.enableSyncDefaultUpdates)) {
2916
- React.unstable_startTransition(() => {
2903
+ React.startTransition(() => {
2904
root.render(<App text="First update" />);
2905
});
2906
} else {
@@ -2926,7 +2913,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2913
2914
// Update again. This should also suspend for a JND.
2915
if (gate(flags => flags.enableSyncDefaultUpdates)) {
2929
- React.unstable_startTransition(() => {
2916
+ React.startTransition(() => {
2917
root.render(<App text="Second update" />);
2918
});
2919
} else {
@@ -2992,7 +2979,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
2979
expect(root).toMatchRenderedOutput(<span prop="Foo" />);
2980
});
2981
2995
- // @gate experimental
2982
// @gate enableCache
2983
it('should not render hidden content while suspended on higher pri', async () => {
2984
function Offscreen() {
@@ -3021,7 +3007,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3007
expect(ReactNoop).toMatchRenderedOutput(<div hidden={true} />);
3008
3009
// Start transition.
3024
- React.unstable_startTransition(() => {
3010
+ React.startTransition(() => {
3011
ReactNoop.render(<App showContent={true} />);
3012
});
3013
@@ -3043,7 +3029,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3029
);
3030
});
3031
3046
- // @gate experimental
3032
// @gate enableCache
3033
it('should be able to unblock higher pri content before suspended hidden', async () => {
3034
function Offscreen() {
@@ -3074,7 +3059,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3059
expect(Scheduler).toFlushAndYieldThrough(['Suspend! [A]']);
3060
3061
// Start transition.
3077
- React.unstable_startTransition(() => {
3062
+ React.startTransition(() => {
3063
ReactNoop.render(<App showContent={true} />);
3064
});
3065
@@ -3272,7 +3257,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3257
// update even though the primary tree is suspended.
3258
await ReactNoop.act(async () => {
3259
setAppText('C');
3275
- React.unstable_startTransition(() => {
3260
+ React.startTransition(() => {
3261
setFallbackText('Still loading...');
3262
});
3263
});
@@ -3705,11 +3690,10 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3690
);
3691
});
3692
3708
- // @gate experimental
3693
// @gate enableCache
3694
// @gate !enableSyncDefaultUpdates
3695
it('regression: ping at high priority causes update to be dropped', async () => {
3712
- const {useState, unstable_useTransition: useTransition} = React;
3696
+ const {useState, useTransition} = React;
3697
3698
let setTextA;
3699
function A() {
@@ -3818,15 +3802,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
3802
});
3803
3804
// Regression: https://github.com/facebook/react/issues/18486
3821
- // @gate experimental
3805
// @gate enableCache
3806
it('does not get stuck in pending state with render phase updates', async () => {
3807
let setTextWithShortTransition;
3808
let setTextWithLongTransition;
3809
3810
function App() {
3828
- const [isPending1, startShortTransition] = React.unstable_useTransition();
3829
- const [isPending2, startLongTransition] = React.unstable_useTransition();
3811
+ const [isPending1, startShortTransition] = React.useTransition();
3812
+ const [isPending2, startLongTransition] = React.useTransition();
3813
const isPending = isPending1 || isPending2;
3814
const [text, setText] = React.useState('');
3815
const [mirror, setMirror] = React.useState('');
packages/react-reconciler/src/__tests__/ReactTransition-test.js
+3
-15
@@ -32,9 +32,9 @@ describe('ReactTransition', () => {
32
Scheduler = require('scheduler');
33
useState = React.useState;
34
useLayoutEffect = React.useLayoutEffect;
35
- useTransition = React.unstable_useTransition;
35
+ useTransition = React.useTransition;
36
Suspense = React.Suspense;
37
- startTransition = React.unstable_startTransition;
37
+ startTransition = React.startTransition;
38
getCacheForType = React.unstable_getCacheForType;
39
act = ReactNoop.act;
40
@@ -158,7 +158,6 @@ describe('ReactTransition', () => {
158
}
159
}
160
161
- // @gate experimental
161
// @gate enableCache
162
test('isPending works even if called from outside an input event', async () => {
163
let start;
@@ -200,7 +199,6 @@ describe('ReactTransition', () => {
199
expect(root).toMatchRenderedOutput('Async');
200
});
201
203
- // @gate experimental
202
// @gate enableCache
203
test(
204
'when multiple transitions update the same queue, only the most recent ' +
@@ -320,7 +318,6 @@ describe('ReactTransition', () => {
318
);
319
320
// Same as previous test, but for class update queue.
323
- // @gate experimental
321
// @gate enableCache
322
test(
323
'when multiple transitions update the same queue, only the most recent ' +
@@ -445,7 +442,6 @@ describe('ReactTransition', () => {
442
},
443
);
444
448
- // @gate experimental
445
// @gate enableCache
446
test(
447
'when multiple transitions update overlapping queues, all the transitions ' +
@@ -551,7 +547,6 @@ describe('ReactTransition', () => {
547
},
548
);
549
554
- // @gate experimental
550
// @gate enableCache
551
test('interrupt a refresh transition if a new transition is scheduled', async () => {
552
const root = ReactNoop.createRoot();
@@ -607,7 +602,6 @@ describe('ReactTransition', () => {
602
expect(root).toMatchRenderedOutput('Updated');
603
});
604
610
- // @gate experimental
605
// @gate enableCache
606
test(
607
"interrupt a refresh transition when something suspends and we've " +
@@ -669,7 +663,7 @@ describe('ReactTransition', () => {
663
expect(Scheduler).toFlushAndYieldThrough(['A']);
664
665
// Now schedule a second transition. We won't interrupt the first one.
672
- React.unstable_startTransition(() => {
666
+ React.startTransition(() => {
667
setShouldHideInParent(true);
668
});
669
// Continue rendering the first transition.
@@ -710,7 +704,6 @@ describe('ReactTransition', () => {
704
},
705
);
706
713
- // @gate experimental
707
// @gate enableCache
708
test(
709
'interrupt a refresh transition when something suspends and a parent ' +
@@ -776,8 +769,6 @@ describe('ReactTransition', () => {
769
},
770
);
771
779
- // @gate experimental
780
- // @gate enableCache
772
it('should render normal pri updates scheduled after transitions before transitions', async () => {
773
let updateTransitionPri;
774
let updateNormalPri;
@@ -833,7 +824,6 @@ describe('ReactTransition', () => {
824
expect(root).toMatchRenderedOutput('Transition pri: 1, Normal pri: 1');
825
});
826
836
- // @gate experimental
827
// @gate enableCache
828
it('should render normal pri updates before transition suspense retries', async () => {
829
let updateTransitionPri;
@@ -898,8 +888,6 @@ describe('ReactTransition', () => {
888
expect(root).toMatchRenderedOutput('Async, Normal pri: 1');
889
});
890
901
- // @gate experimental
902
- // @gate enableCache
891
it('should not interrupt transitions with normal pri updates', async () => {
892
let updateNormalPri;
893
let updateTransitionPri;
packages/react-reconciler/src/__tests__/ReactUpdatePriority-test.js
+1
-2
@@ -15,7 +15,7 @@ describe('ReactUpdatePriority', () => {
15
Scheduler = require('scheduler');
16
ContinuousEventPriority = require('react-reconciler/constants')
17
.ContinuousEventPriority;
18
- startTransition = React.unstable_startTransition;
18
+ startTransition = React.startTransition;
19
useState = React.useState;
20
useEffect = React.useEffect;
21
});
@@ -84,7 +84,6 @@ describe('ReactUpdatePriority', () => {
84
expect(Scheduler).toHaveYielded(['Idle: 2, Default: 2']);
85
});
86
87
- // @gate experimental
87
test('continuous updates should interrupt transisions', async () => {
88
const root = ReactNoop.createRoot();
89
packages/react-reconciler/src/__tests__/ReactUpdaters-test.internal.js
+4
-7
@@ -153,7 +153,6 @@ describe('updaters', () => {
153
expect(allSchedulerTypes).toEqual([[null], [SchedulingComponent]]);
154
});
155
156
- // @gate experimental
156
it('should cover cascading updates', async () => {
157
let triggerActiveCascade = null;
158
let triggerPassiveCascade = null;
@@ -183,7 +182,7 @@ describe('updaters', () => {
182
return count;
183
};
184
186
- const root = ReactDOM.unstable_createRoot(document.createElement('div'));
185
+ const root = ReactDOM.createRoot(document.createElement('div'));
186
await ReactTestUtils.act(async () => {
187
root.render(<Parent />);
188
expect(Scheduler).toFlushAndYieldThrough([
@@ -292,7 +291,6 @@ describe('updaters', () => {
291
done();
292
});
293
295
- // @gate experimental
294
it('should cover error handling', async () => {
295
let triggerError = null;
296
@@ -329,7 +327,7 @@ describe('updaters', () => {
327
throw new Error('Hello');
328
};
329
332
- const root = ReactDOM.unstable_createRoot(document.createElement('div'));
330
+ const root = ReactDOM.createRoot(document.createElement('div'));
331
await ReactTestUtils.act(async () => {
332
root.render(<Parent shouldError={false} />);
333
});
@@ -349,7 +347,6 @@ describe('updaters', () => {
347
Scheduler.unstable_flushAll();
348
});
349
352
- // @gate experimental
350
it('should distinguish between updaters in the case of interleaved work', async () => {
351
const {
352
FunctionComponent,
@@ -368,7 +365,7 @@ describe('updaters', () => {
365
const LowPriorityUpdater = () => {
366
const [count, setCount] = React.useState(0);
367
triggerLowPriorityUpdate = () => {
371
- React.unstable_startTransition(() => {
368
+ React.startTransition(() => {
369
setCount(prevCount => prevCount + 1);
370
});
371
};
@@ -380,7 +377,7 @@ describe('updaters', () => {
377
return null;
378
};
379
383
- const root = ReactDOM.unstable_createRoot(document.createElement('div'));
380
+ const root = ReactDOM.createRoot(document.createElement('div'));
381
root.render(
382
<React.Fragment>
383
<SyncPriorityUpdater />
packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js
+1
-2
@@ -149,7 +149,6 @@ describe('SchedulingProfiler', () => {
149
});
150
151
// @gate enableSchedulingProfiler
152
- // @gate experimental || !enableSyncDefaultUpdates
152
it('should mark render yields', async () => {
153
function Bar() {
154
Scheduler.unstable_yieldValue('Bar');
@@ -162,7 +161,7 @@ describe('SchedulingProfiler', () => {
161
}
162
163
if (gate(flags => flags.enableSyncDefaultUpdates)) {
165
- React.unstable_startTransition(() => {
164
+ React.startTransition(() => {
165
ReactNoop.render(<Foo />);
166
});
167
packages/react-reconciler/src/__tests__/SchedulingProfilerLabels-test.internal.js
-3
@@ -100,7 +100,6 @@ describe('SchedulingProfiler labels', () => {
100
);
101
});
102
103
- // @gate experimental
103
// @gate enableSchedulingProfiler
104
it('regression test DefaultLane', () => {
105
const container = document.createElement('div');
@@ -114,7 +113,6 @@ describe('SchedulingProfiler labels', () => {
113
});
114
});
115
117
- // @gate experimental
116
// @gate enableSchedulingProfiler
117
// @gate !enableLegacyFBSupport
118
it('regression test InputDiscreteLane', () => {
@@ -144,7 +142,6 @@ describe('SchedulingProfiler labels', () => {
142
);
143
});
144
147
- // @gate experimental
145
// @gate enableSchedulingProfiler
146
it('regression test InputContinuousLane', () => {
147
const container = document.createElement('div');
packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js
+16
-47
@@ -31,8 +31,11 @@ function loadModules() {
31
ReactNoop = require('react-noop-renderer');
32
Scheduler = require('scheduler');
33
act = ReactNoop.act;
34
- createMutableSource = React.unstable_createMutableSource;
35
- useMutableSource = React.unstable_useMutableSource;
34
+
35
+ // Stable entrypoints export with "unstable_" prefix.
36
+ createMutableSource =
37
+ React.createMutableSource || React.unstable_createMutableSource;
38
+ useMutableSource = React.useMutableSource || React.unstable_useMutableSource;
39
}
40
41
describe('useMutableSource', () => {
@@ -138,7 +141,6 @@ describe('useMutableSource', () => {
141
142
beforeEach(loadModules);
143
141
- // @gate experimental
144
it('should subscribe to a source and schedule updates when it changes', () => {
145
const source = createSource('one');
146
const mutableSource = createMutableSource(source, param => param.version);
@@ -206,14 +208,13 @@ describe('useMutableSource', () => {
208
});
209
});
210
209
- // @gate experimental
211
it('should restart work if a new source is mutated during render', () => {
212
const source = createSource('one');
213
const mutableSource = createMutableSource(source, param => param.version);
214
215
act(() => {
216
if (gate(flags => flags.enableSyncDefaultUpdates)) {
216
- React.unstable_startTransition(() => {
217
+ React.startTransition(() => {
218
ReactNoop.render(
219
<>
220
<Component
@@ -262,7 +263,6 @@ describe('useMutableSource', () => {
263
});
264
});
265
265
- // @gate experimental
266
it('should schedule an update if a new source is mutated between render and commit (subscription)', () => {
267
const source = createSource('one');
268
const mutableSource = createMutableSource(source, param => param.version);
@@ -302,7 +302,6 @@ describe('useMutableSource', () => {
302
});
303
});
304
305
- // @gate experimental
305
it('should unsubscribe and resubscribe if a new source is used', () => {
306
const sourceA = createSource('a-one');
307
const mutableSourceA = createMutableSource(
@@ -359,7 +358,6 @@ describe('useMutableSource', () => {
358
});
359
});
360
362
- // @gate experimental
361
it('should unsubscribe and resubscribe if a new subscribe function is provided', () => {
362
const source = createSource('a-one');
363
const mutableSource = createMutableSource(source, param => param.version);
@@ -424,7 +422,6 @@ describe('useMutableSource', () => {
422
});
423
});
424
427
- // @gate experimental
425
it('should re-use previously read snapshot value when reading is unsafe', () => {
426
const source = createSource('one');
427
const mutableSource = createMutableSource(source, param => param.version);
@@ -452,7 +449,7 @@ describe('useMutableSource', () => {
449
// Changing values should schedule an update with React.
450
// Start working on this update but don't finish it.
451
if (gate(flags => flags.enableSyncDefaultUpdates)) {
455
- React.unstable_startTransition(() => {
452
+ React.startTransition(() => {
453
source.value = 'two';
454
});
455
} else {
@@ -487,7 +484,6 @@ describe('useMutableSource', () => {
484
});
485
});
486
490
- // @gate experimental
487
it('should read from source on newly mounted subtree if no pending updates are scheduled for source', () => {
488
const source = createSource('one');
489
const mutableSource = createMutableSource(source, param => param.version);
@@ -527,7 +523,6 @@ describe('useMutableSource', () => {
523
});
524
});
525
530
- // @gate experimental
526
it('should throw and restart render if source and snapshot are unavailable during an update', () => {
527
const source = createSource('one');
528
const mutableSource = createMutableSource(source, param => param.version);
@@ -591,7 +586,6 @@ describe('useMutableSource', () => {
586
});
587
});
588
594
- // @gate experimental
589
it('should throw and restart render if source and snapshot are unavailable during a sync update', () => {
590
const source = createSource('one');
591
const mutableSource = createMutableSource(source, param => param.version);
@@ -655,7 +649,6 @@ describe('useMutableSource', () => {
649
});
650
});
651
658
- // @gate experimental
652
it('should only update components whose subscriptions fire', () => {
653
const source = createComplexSource('a:one', 'b:one');
654
const mutableSource = createMutableSource(source, param => param.version);
@@ -694,7 +687,6 @@ describe('useMutableSource', () => {
687
});
688
});
689
697
- // @gate experimental
690
it('should detect tearing in part of the store not yet subscribed to', () => {
691
const source = createComplexSource('a:one', 'b:one');
692
const mutableSource = createMutableSource(source, param => param.version);
@@ -722,7 +714,7 @@ describe('useMutableSource', () => {
714
// Because the store has not changed yet, there are no pending updates,
715
// so it is considered safe to read from when we start this render.
716
if (gate(flags => flags.enableSyncDefaultUpdates)) {
725
- React.unstable_startTransition(() => {
717
+ React.startTransition(() => {
718
ReactNoop.render(
719
<>
720
<Component
@@ -787,7 +779,6 @@ describe('useMutableSource', () => {
779
});
780
});
781
790
- // @gate experimental
782
it('does not schedule an update for subscriptions that fire with an unchanged snapshot', () => {
783
const MockComponent = jest.fn(Component);
784
@@ -814,7 +805,6 @@ describe('useMutableSource', () => {
805
});
806
});
807
817
- // @gate experimental
808
it('should throw and restart if getSnapshot changes between scheduled update and re-render', () => {
809
const source = createSource('one');
810
const mutableSource = createMutableSource(source, param => param.version);
@@ -855,7 +845,6 @@ describe('useMutableSource', () => {
845
});
846
});
847
858
- // @gate experimental
848
it('should recover from a mutation during yield when other work is scheduled', () => {
849
const source = createSource('one');
850
const mutableSource = createMutableSource(source, param => param.version);
@@ -863,7 +852,7 @@ describe('useMutableSource', () => {
852
act(() => {
853
// Start a render that uses the mutable source.
854
if (gate(flags => flags.enableSyncDefaultUpdates)) {
866
- React.unstable_startTransition(() => {
855
+ React.startTransition(() => {
856
ReactNoop.render(
857
<>
858
<Component
@@ -910,7 +899,6 @@ describe('useMutableSource', () => {
899
});
900
});
901
913
- // @gate experimental
902
it('should not throw if the new getSnapshot returns the same snapshot value', () => {
903
const source = createSource('one');
904
const mutableSource = createMutableSource(source, param => param.version);
@@ -965,7 +953,6 @@ describe('useMutableSource', () => {
953
});
954
});
955
968
- // @gate experimental
956
it('should not throw if getSnapshot changes but the source can be safely read from anyway', () => {
957
const source = createSource('one');
958
const mutableSource = createMutableSource(source, param => param.version);
@@ -1005,7 +992,6 @@ describe('useMutableSource', () => {
992
});
993
});
994
1008
- // @gate experimental
995
it('should still schedule an update if an eager selector throws after a mutation', () => {
996
const source = createSource({
997
friends: [
@@ -1072,7 +1058,6 @@ describe('useMutableSource', () => {
1058
});
1059
});
1060
1075
- // @gate experimental
1061
it('should not warn about updates that fire between unmount and passive unsubscribe', () => {
1062
const source = createSource('one');
1063
const mutableSource = createMutableSource(source, param => param.version);
@@ -1109,7 +1094,6 @@ describe('useMutableSource', () => {
1094
});
1095
});
1096
1112
- // @gate experimental
1097
it('should support inline selectors and updates that are processed after selector change', async () => {
1098
const source = createSource({
1099
a: 'initial',
@@ -1154,7 +1138,6 @@ describe('useMutableSource', () => {
1138
expect(root).toMatchRenderedOutput('Another update');
1139
});
1140
1157
- // @gate experimental
1141
it('should clear the update queue when getSnapshot changes with pending lower priority updates', async () => {
1142
const source = createSource({
1143
a: 'initial',
@@ -1211,7 +1194,6 @@ describe('useMutableSource', () => {
1194
expect(root).toMatchRenderedOutput('B: Update');
1195
});
1196
1214
- // @gate experimental
1197
it('should clear the update queue when source changes with pending lower priority updates', async () => {
1198
const sourceA = createSource('initial');
1199
const sourceB = createSource('initial');
@@ -1256,7 +1238,6 @@ describe('useMutableSource', () => {
1238
expect(root).toMatchRenderedOutput('B: Update');
1239
});
1240
1259
- // @gate experimental
1241
it('should always treat reading as potentially unsafe when getSnapshot changes between renders', async () => {
1242
const source = createSource({
1243
a: 'foo',
@@ -1346,7 +1327,6 @@ describe('useMutableSource', () => {
1327
expect(Scheduler).toHaveYielded(['x: bar, y: bar']);
1328
});
1329
1349
- // @gate experimental
1330
it('getSnapshot changes and then source is mutated in between paint and passive effect phase', async () => {
1331
const source = createSource({
1332
a: 'foo',
@@ -1405,7 +1385,6 @@ describe('useMutableSource', () => {
1385
expect(root).toMatchRenderedOutput('baz');
1386
});
1387
1408
- // @gate experimental
1388
it('getSnapshot changes and then source is mutated in between paint and passive effect phase, case 2', async () => {
1389
const source = createSource({
1390
a: 'a0',
@@ -1476,7 +1455,6 @@ describe('useMutableSource', () => {
1455
expect(root.getChildrenAsJSX()).toEqual('first: a1, second: a1');
1456
});
1457
1479
- // @gate experimental
1458
it(
1459
'if source is mutated after initial read but before subscription is set ' +
1460
'up, should still entangle all pending mutations even if snapshot of ' +
@@ -1533,7 +1511,7 @@ describe('useMutableSource', () => {
1511
1512
await act(async () => {
1513
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1536
- React.unstable_startTransition(() => {
1514
+ React.startTransition(() => {
1515
root.render(
1516
<>
1517
<Read getSnapshot={getSnapshotA} />
@@ -1563,7 +1541,7 @@ describe('useMutableSource', () => {
1541
// read during render will happen to match the latest value. But it should
1542
// still entangle the updates to prevent the previous update (a1) from
1543
// rendering by itself.
1566
- React.unstable_startTransition(() => {
1544
+ React.startTransition(() => {
1545
mutateA('a0');
1546
mutateB('b0');
1547
});
@@ -1581,7 +1559,6 @@ describe('useMutableSource', () => {
1559
},
1560
);
1561
1584
- // @gate experimental
1562
it('warns about functions being used as snapshot values', async () => {
1563
const source = createSource(() => 'a');
1564
const mutableSource = createMutableSource(source, param => param.version);
@@ -1609,7 +1586,6 @@ describe('useMutableSource', () => {
1586
expect(root).toMatchRenderedOutput('a');
1587
});
1588
1612
- // @gate experimental
1589
it('getSnapshot changes and then source is mutated during interleaved event', async () => {
1590
const {useEffect} = React;
1591
@@ -1680,7 +1656,7 @@ describe('useMutableSource', () => {
1656
await act(async () => {
1657
// Switch the parent and the child to read using the same config
1658
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1683
- React.unstable_startTransition(() => {
1659
+ React.startTransition(() => {
1660
root.render(<App parentConfig={configB} childConfig={configB} />);
1661
});
1662
} else {
@@ -1692,7 +1668,7 @@ describe('useMutableSource', () => {
1668
// Mutate the config. This is at lower priority so that 1) to make sure
1669
// it doesn't happen to get batched with the in-progress render, and 2)
1670
// so it doesn't interrupt the in-progress render.
1695
- React.unstable_startTransition(() => {
1671
+ React.startTransition(() => {
1672
source.valueB = '3';
1673
});
1674
@@ -1734,7 +1710,6 @@ describe('useMutableSource', () => {
1710
});
1711
});
1712
1737
- // @gate experimental
1713
it('should not tear with newly mounted component when updates were scheduled at a lower priority', async () => {
1714
const source = createSource('one');
1715
const mutableSource = createMutableSource(source, param => param.version);
@@ -1802,7 +1777,7 @@ describe('useMutableSource', () => {
1777
expect(source.listenerCount).toBe(1);
1778
1779
// Mutate -> schedule update for ComponentA
1805
- React.unstable_startTransition(() => {
1780
+ React.startTransition(() => {
1781
source.value = 'two';
1782
});
1783
@@ -1815,7 +1790,6 @@ describe('useMutableSource', () => {
1790
if (__DEV__) {
1791
// See https://github.com/facebook/react/issues/19948
1792
describe('side effecte detection', () => {
1818
- // @gate experimental
1793
it('should throw if a mutable source is mutated during render', () => {
1794
const source = createSource(0);
1795
const mutableSource = createMutableSource(
@@ -1860,7 +1834,6 @@ describe('useMutableSource', () => {
1834
]);
1835
});
1836
1863
- // @gate experimental
1837
it('should throw if a mutable source is mutated during render (legacy mode)', () => {
1838
const source = createSource('initial');
1839
const mutableSource = createMutableSource(
@@ -1899,7 +1872,6 @@ describe('useMutableSource', () => {
1872
expect(Scheduler).toHaveYielded(['MutateDuringRead:initial']);
1873
});
1874
1902
- // @gate experimental
1875
it('should not misidentify mutations after render as side effects', async () => {
1876
const source = createSource('initial');
1877
const mutableSource = createMutableSource(
@@ -1934,7 +1906,6 @@ describe('useMutableSource', () => {
1906
});
1907
1908
describe('dev warnings', () => {
1937
- // @gate experimental
1909
it('should warn if the subscribe function does not return an unsubscribe function', () => {
1910
const source = createSource('one');
1911
const mutableSource = createMutableSource(
@@ -1960,7 +1931,6 @@ describe('useMutableSource', () => {
1931
);
1932
});
1933
1963
- // @gate experimental
1934
it('should error if multiple renderers of the same type use a mutable source at the same time', () => {
1935
const source = createSource('one');
1936
const mutableSource = createMutableSource(
@@ -1971,7 +1941,7 @@ describe('useMutableSource', () => {
1941
act(() => {
1942
// Start a render that uses the mutable source.
1943
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1974
- React.unstable_startTransition(() => {
1944
+ React.startTransition(() => {
1945
ReactNoop.render(
1946
<>
1947
<Component
@@ -2041,7 +2011,6 @@ describe('useMutableSource', () => {
2011
});
2012
});
2013
2044
- // @gate experimental
2014
it('should error if multiple renderers of the same type use a mutable source at the same time with mutation between', () => {
2015
const source = createSource('one');
2016
const mutableSource = createMutableSource(
@@ -2052,7 +2021,7 @@ describe('useMutableSource', () => {
2021
act(() => {
2022
// Start a render that uses the mutable source.
2023
if (gate(flags => flags.enableSyncDefaultUpdates)) {
2055
- React.unstable_startTransition(() => {
2024
+ React.startTransition(() => {
2025
ReactNoop.render(
2026
<>
2027
<Component
packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js
+14
-15
@@ -27,8 +27,12 @@ describe('useMutableSourceHydration', () => {
27
Scheduler = require('scheduler');
28
29
act = require('react-dom/test-utils').unstable_concurrentAct;
30
- createMutableSource = React.unstable_createMutableSource;
31
- useMutableSource = React.unstable_useMutableSource;
30
+
31
+ // Stable entrypoints export with "unstable_" prefix.
32
+ createMutableSource =
33
+ React.createMutableSource || React.unstable_createMutableSource;
34
+ useMutableSource =
35
+ React.useMutableSource || React.unstable_useMutableSource;
36
});
37
38
function dispatchAndSetCurrentEvent(el, event) {
@@ -140,7 +144,6 @@ describe('useMutableSourceHydration', () => {
144
return <div>{`${label}:${snapshot}`}</div>;
145
}
146
143
- // @gate experimental
147
it('should render and hydrate', () => {
148
const source = createSource('one');
149
const mutableSource = createMutableSource(source, param => param.version);
@@ -164,7 +167,7 @@ describe('useMutableSourceHydration', () => {
167
expect(Scheduler).toHaveYielded(['only:one']);
168
expect(source.listenerCount).toBe(0);
169
167
- const root = ReactDOM.unstable_createRoot(container, {
170
+ const root = ReactDOM.createRoot(container, {
171
hydrate: true,
172
hydrationOptions: {
173
mutableSources: [mutableSource],
@@ -177,7 +180,6 @@ describe('useMutableSourceHydration', () => {
180
expect(source.listenerCount).toBe(1);
181
});
182
180
- // @gate experimental
183
it('should detect a tear before hydrating a component', () => {
184
const source = createSource('one');
185
const mutableSource = createMutableSource(source, param => param.version);
@@ -201,7 +203,7 @@ describe('useMutableSourceHydration', () => {
203
expect(Scheduler).toHaveYielded(['only:one']);
204
expect(source.listenerCount).toBe(0);
205
204
- const root = ReactDOM.unstable_createRoot(container, {
206
+ const root = ReactDOM.createRoot(container, {
207
hydrate: true,
208
hydrationOptions: {
209
mutableSources: [mutableSource],
@@ -222,7 +224,6 @@ describe('useMutableSourceHydration', () => {
224
expect(source.listenerCount).toBe(1);
225
});
226
225
- // @gate experimental
227
it('should detect a tear between hydrating components', () => {
228
const source = createSource('one');
229
const mutableSource = createMutableSource(source, param => param.version);
@@ -254,7 +255,7 @@ describe('useMutableSourceHydration', () => {
255
expect(Scheduler).toHaveYielded(['a:one', 'b:one']);
256
expect(source.listenerCount).toBe(0);
257
257
- const root = ReactDOM.unstable_createRoot(container, {
258
+ const root = ReactDOM.createRoot(container, {
259
hydrate: true,
260
hydrationOptions: {
261
mutableSources: [mutableSource],
@@ -263,7 +264,7 @@ describe('useMutableSourceHydration', () => {
264
expect(() => {
265
act(() => {
266
if (gate(flags => flags.enableSyncDefaultUpdates)) {
266
- React.unstable_startTransition(() => {
267
+ React.startTransition(() => {
268
root.render(<TestComponent />);
269
});
270
} else {
@@ -281,7 +282,6 @@ describe('useMutableSourceHydration', () => {
282
expect(source.listenerCount).toBe(2);
283
});
284
284
- // @gate experimental
285
it('should detect a tear between hydrating components reading from different parts of a source', () => {
286
const source = createComplexSource('a:one', 'b:one');
287
const mutableSource = createMutableSource(source, param => param.version);
@@ -314,7 +314,7 @@ describe('useMutableSourceHydration', () => {
314
container.innerHTML = htmlString;
315
expect(Scheduler).toHaveYielded(['0:a:one', '1:b:one']);
316
317
- const root = ReactDOM.unstable_createRoot(container, {
317
+ const root = ReactDOM.createRoot(container, {
318
hydrate: true,
319
hydrationOptions: {
320
mutableSources: [mutableSource],
@@ -323,7 +323,7 @@ describe('useMutableSourceHydration', () => {
323
expect(() => {
324
act(() => {
325
if (gate(flags => flags.enableSyncDefaultUpdates)) {
326
- React.unstable_startTransition(() => {
326
+ React.startTransition(() => {
327
root.render(
328
<>
329
<Component
@@ -370,7 +370,6 @@ describe('useMutableSourceHydration', () => {
370
expect(Scheduler).toHaveYielded(['0:a:one', '1:b:two']);
371
});
372
373
- // @gate experimental
373
// @gate !enableSyncDefaultUpdates
374
it('should detect a tear during a higher priority interruption', () => {
375
const source = createSource('one');
@@ -405,7 +404,7 @@ describe('useMutableSourceHydration', () => {
404
expect(Scheduler).toHaveYielded([1, 'a:one']);
405
expect(source.listenerCount).toBe(0);
406
408
- const root = ReactDOM.unstable_createRoot(container, {
407
+ const root = ReactDOM.createRoot(container, {
408
hydrate: true,
409
hydrationOptions: {
410
mutableSources: [mutableSource],
@@ -415,7 +414,7 @@ describe('useMutableSourceHydration', () => {
414
expect(() => {
415
act(() => {
416
if (gate(flags => flags.enableSyncDefaultUpdates)) {
418
- React.unstable_startTransition(() => {
417
+ React.startTransition(() => {
418
root.render(<TestComponent flag={1} />);
419
});
420
} else {
packages/react-refresh/src/__tests__/ReactFresh-test.js
+1
-1
@@ -2437,7 +2437,7 @@ describe('ReactFresh', () => {
2437
};
2438
});
2439
2440
- const root = ReactDOM.unstable_createRoot(container);
2440
+ const root = ReactDOM.createRoot(container);
2441
root.render(<AppV1 offscreen={true} />);
2442
expect(Scheduler).toFlushAndYieldThrough(['App#layout']);
2443
const el = container.firstChild;
packages/react-server-dom-relay/src/__tests__/ReactFlightDOMRelay-test.internal.js
-2
@@ -72,7 +72,6 @@ describe('ReactFlightDOMRelay', () => {
72
});
73
});
74
75
- // @gate experimental
75
it('can render a client component using a module reference and render there', () => {
76
function UserClient(props) {
77
return (
@@ -105,7 +104,6 @@ describe('ReactFlightDOMRelay', () => {
104
expect(container.innerHTML).toEqual('<span>Hello, Seb Smith</span>');
105
});
106
108
- // @gate experimental
107
it('can reasonably handle different element types', () => {
108
const {
109
forwardRef,
packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js
+5
-10
@@ -128,7 +128,6 @@ describe('ReactFlightDOM', () => {
128
});
129
});
130
131
- // @gate experimental
131
it('should resolve the root', async () => {
132
const {Suspense} = React;
133
@@ -171,7 +170,7 @@ describe('ReactFlightDOM', () => {
170
const response = ReactServerDOMReader.createFromReadableStream(readable);
171
172
const container = document.createElement('div');
174
- const root = ReactDOM.unstable_createRoot(container);
173
+ const root = ReactDOM.createRoot(container);
174
await act(async () => {
175
root.render(<App response={response} />);
176
});
@@ -180,7 +179,6 @@ describe('ReactFlightDOM', () => {
179
);
180
});
181
183
- // @gate experimental
182
it('should not get confused by $', async () => {
183
const {Suspense} = React;
184
@@ -210,14 +208,13 @@ describe('ReactFlightDOM', () => {
208
const response = ReactServerDOMReader.createFromReadableStream(readable);
209
210
const container = document.createElement('div');
213
- const root = ReactDOM.unstable_createRoot(container);
211
+ const root = ReactDOM.createRoot(container);
212
await act(async () => {
213
root.render(<App response={response} />);
214
});
215
expect(container.innerHTML).toBe('<p>$1</p>');
216
});
217
220
- // @gate experimental
218
it('should not get confused by @', async () => {
219
const {Suspense} = React;
220
@@ -247,14 +244,13 @@ describe('ReactFlightDOM', () => {
244
const response = ReactServerDOMReader.createFromReadableStream(readable);
245
246
const container = document.createElement('div');
250
- const root = ReactDOM.unstable_createRoot(container);
247
+ const root = ReactDOM.createRoot(container);
248
await act(async () => {
249
root.render(<App response={response} />);
250
});
251
expect(container.innerHTML).toBe('<p>@div</p>');
252
});
253
257
- // @gate experimental
254
it('should progressively reveal server components', async () => {
255
let reportedErrors = [];
256
const {Suspense} = React;
@@ -383,7 +379,7 @@ describe('ReactFlightDOM', () => {
379
const response = ReactServerDOMReader.createFromReadableStream(readable);
380
381
const container = document.createElement('div');
386
- const root = ReactDOM.unstable_createRoot(container);
382
+ const root = ReactDOM.createRoot(container);
383
await act(async () => {
384
root.render(
385
<Suspense fallback={<p>(loading)</p>}>
@@ -454,7 +450,6 @@ describe('ReactFlightDOM', () => {
450
expect(reportedErrors).toEqual([]);
451
});
452
457
- // @gate experimental
453
it('should preserve state of client components on refetch', async () => {
454
const {Suspense} = React;
455
@@ -483,7 +478,7 @@ describe('ReactFlightDOM', () => {
478
}
479
480
const container = document.createElement('div');
486
- const root = ReactDOM.unstable_createRoot(container);
481
+ const root = ReactDOM.createRoot(container);
482
483
const stream1 = getTestStream();
484
ReactServerDOMWriter.pipeToNodeWritable(
packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js
+2
-4
@@ -73,7 +73,6 @@ describe('ReactTestRendererAsync', () => {
73
expect(renderer.toJSON()).toEqual(['A:2', 'B:2', 'C:2']);
74
});
75
76
- // @gate experimental || !enableSyncDefaultUpdates
76
it('flushThrough flushes until the expected values is yielded', () => {
77
function Child(props) {
78
Scheduler.unstable_yieldValue(props.children);
@@ -91,7 +90,7 @@ describe('ReactTestRendererAsync', () => {
90
91
let renderer;
92
if (gate(flags => flags.enableSyncDefaultUpdates)) {
94
- React.unstable_startTransition(() => {
93
+ React.startTransition(() => {
94
renderer = ReactTestRenderer.create(<Parent step={1} />, {
95
unstable_isConcurrent: true,
96
});
@@ -112,7 +111,6 @@ describe('ReactTestRendererAsync', () => {
111
expect(renderer.toJSON()).toEqual(['A:1', 'B:1', 'C:1']);
112
});
113
115
- // @gate experimental || !enableSyncDefaultUpdates
114
it('supports high priority interruptions', () => {
115
function Child(props) {
116
Scheduler.unstable_yieldValue(props.children);
@@ -138,7 +136,7 @@ describe('ReactTestRendererAsync', () => {
136
137
let renderer;
138
if (gate(flags => flags.enableSyncDefaultUpdates)) {
141
- React.unstable_startTransition(() => {
139
+ React.startTransition(() => {
140
renderer = ReactTestRenderer.create(<Example step={1} />, {
141
unstable_isConcurrent: true,
142
});
packages/react/index.classic.fb.js
+30
-33
@@ -8,55 +8,52 @@
8
*/
9
10
export {
11
+ __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
12
Children,
12
- createRef,
13
Component,
14
+ Fragment,
15
+ Profiler,
16
PureComponent,
17
+ StrictMode,
18
+ Suspense,
19
+ SuspenseList,
20
+ SuspenseList as unstable_SuspenseList, // TODO: Remove once call sights updated to SuspenseList
21
+ cloneElement,
22
createContext,
23
+ createElement,
24
+ createFactory,
25
+ createMutableSource,
26
+ createMutableSource as unstable_createMutableSource,
27
+ createRef,
28
forwardRef,
29
+ isValidElement,
30
lazy,
31
memo,
32
+ startTransition,
33
+ startTransition as unstable_startTransition, // TODO: Remove once call sights updated to startTransition
34
+ unstable_Cache,
35
+ unstable_DebugTracingMode,
36
+ unstable_LegacyHidden,
37
+ unstable_Scope,
38
+ unstable_getCacheForType,
39
+ unstable_useCacheRefresh,
40
+ unstable_useOpaqueIdentifier,
41
useCallback,
42
useContext,
43
+ useDebugValue,
44
+ useDeferredValue,
45
+ useDeferredValue as unstable_useDeferredValue, // TODO: Remove once call sights updated to useDeferredValue
46
useEffect,
47
useImperativeHandle,
23
- useDebugValue,
48
useLayoutEffect,
49
useMemo,
50
+ useMutableSource,
51
+ useMutableSource as unstable_useMutableSource,
52
useReducer,
53
useRef,
54
useState,
29
- useMutableSource,
30
- useMutableSource as unstable_useMutableSource,
31
- createMutableSource,
32
- createMutableSource as unstable_createMutableSource,
33
- Fragment,
34
- Profiler,
35
- StrictMode,
36
- Suspense,
37
- unstable_LegacyHidden,
38
- createElement,
39
- cloneElement,
40
- isValidElement,
41
- version,
42
- __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
43
- createFactory,
44
- // exposeConcurrentModeAPIs
55
useTransition,
46
- useTransition as unstable_useTransition,
47
- useDeferredValue,
48
- useDeferredValue as unstable_useDeferredValue,
49
- startTransition,
50
- startTransition as unstable_startTransition,
51
- SuspenseList,
52
- SuspenseList as unstable_SuspenseList,
53
- unstable_getCacheForType,
54
- unstable_Cache,
55
- unstable_useCacheRefresh,
56
- // enableScopeAPI
57
- unstable_Scope,
58
- unstable_useOpaqueIdentifier,
59
- // enableDebugTracing
60
- unstable_DebugTracingMode,
56
+ useTransition as unstable_useTransition, // TODO: Remove once call sights updated to useTransition
57
+ version,
58
} from './src/React';
59
export {jsx, jsxs, jsxDEV} from './src/jsx/ReactJSX';
packages/react/index.experimental.js
+23
-25
@@ -8,46 +8,44 @@
8
*/
9
10
export {
11
+ __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
12
Children,
12
- createRef,
13
Component,
14
+ Fragment,
15
+ Profiler,
16
PureComponent,
17
+ StrictMode,
18
+ Suspense,
19
+ SuspenseList,
20
+ cloneElement,
21
createContext,
22
+ createElement,
23
+ createFactory,
24
+ createMutableSource as unstable_createMutableSource,
25
+ createRef,
26
forwardRef,
27
+ isValidElement,
28
lazy,
29
memo,
30
+ startTransition,
31
+ unstable_Cache,
32
+ unstable_DebugTracingMode,
33
+ unstable_LegacyHidden,
34
+ unstable_getCacheForType,
35
+ unstable_useCacheRefresh,
36
+ unstable_useOpaqueIdentifier,
37
useCallback,
38
useContext,
39
+ useDebugValue,
40
+ useDeferredValue,
41
useEffect,
42
useImperativeHandle,
23
- useDebugValue,
43
useLayoutEffect,
44
useMemo,
45
+ useMutableSource as unstable_useMutableSource,
46
useReducer,
47
useRef,
48
useState,
29
- useMutableSource as unstable_useMutableSource,
30
- createMutableSource as unstable_createMutableSource,
31
- Fragment,
32
- Profiler,
33
- StrictMode,
34
- Suspense,
35
- unstable_LegacyHidden,
36
- createElement,
37
- cloneElement,
38
- isValidElement,
49
+ useTransition,
50
version,
40
- __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
41
- createFactory,
42
- // exposeConcurrentModeAPIs
43
- useTransition as unstable_useTransition,
44
- useDeferredValue as unstable_useDeferredValue,
45
- startTransition as unstable_startTransition,
46
- SuspenseList as unstable_SuspenseList,
47
- unstable_useOpaqueIdentifier,
48
- unstable_getCacheForType,
49
- unstable_Cache,
50
- unstable_useCacheRefresh,
51
- // enableDebugTracing
52
- unstable_DebugTracingMode,
51
} from './src/React';
packages/react/index.js
+24
-30
@@ -32,51 +32,45 @@ export type ChildrenArray<+T> = $ReadOnlyArray<ChildrenArray<T>> | T;
32
// Export all exports so that they're available in tests.
33
// We can't use export * from in Flow for some reason.
34
export {
35
+ __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
36
Children,
36
- createRef,
37
Component,
38
+ Fragment,
39
+ Profiler,
40
PureComponent,
41
+ StrictMode,
42
+ Suspense,
43
+ SuspenseList,
44
+ cloneElement,
45
createContext,
46
+ createElement,
47
+ createFactory,
48
+ createMutableSource,
49
+ createRef,
50
forwardRef,
51
+ isValidElement,
52
lazy,
53
memo,
54
+ startTransition,
55
+ unstable_Cache,
56
+ unstable_DebugTracingMode,
57
+ unstable_LegacyHidden,
58
+ unstable_Scope,
59
+ unstable_getCacheForType,
60
+ unstable_useCacheRefresh,
61
+ unstable_useOpaqueIdentifier,
62
useCallback,
63
useContext,
64
+ useDebugValue,
65
+ useDeferredValue,
66
useEffect,
67
useImperativeHandle,
47
- useDebugValue,
68
useLayoutEffect,
69
useMemo,
70
+ useMutableSource,
71
useReducer,
72
useRef,
73
useState,
53
- useMutableSource,
54
- useMutableSource as unstable_useMutableSource,
55
- createMutableSource,
56
- createMutableSource as unstable_createMutableSource,
57
- Fragment,
58
- Profiler,
59
- unstable_DebugTracingMode,
60
- StrictMode,
61
- Suspense,
62
- createElement,
63
- cloneElement,
64
- isValidElement,
65
- version,
66
- __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
67
- createFactory,
74
useTransition,
69
- useTransition as unstable_useTransition,
70
- startTransition,
71
- startTransition as unstable_startTransition,
72
- useDeferredValue,
73
- useDeferredValue as unstable_useDeferredValue,
74
- SuspenseList,
75
- SuspenseList as unstable_SuspenseList,
76
- unstable_LegacyHidden,
77
- unstable_Scope,
78
- unstable_useOpaqueIdentifier,
79
- unstable_getCacheForType,
80
- unstable_Cache,
81
- unstable_useCacheRefresh,
75
+ version,
76
} from './src/React';
packages/react/index.modern.fb.js
+27
-30
@@ -8,54 +8,51 @@
8
*/
9
10
export {
11
+ __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
12
Children,
12
- createRef,
13
Component,
14
+ Fragment,
15
+ Profiler,
16
PureComponent,
17
+ StrictMode,
18
+ Suspense,
19
+ SuspenseList,
20
+ SuspenseList as unstable_SuspenseList, // TODO: Remove once call sights updated to SuspenseList
21
+ cloneElement,
22
createContext,
23
+ createElement,
24
+ createMutableSource,
25
+ createMutableSource as unstable_createMutableSource,
26
+ createRef,
27
forwardRef,
28
+ isValidElement,
29
lazy,
30
memo,
31
+ startTransition,
32
+ startTransition as unstable_startTransition, // TODO: Remove once call sights updated to startTransition
33
+ unstable_Cache,
34
+ unstable_DebugTracingMode,
35
+ unstable_LegacyHidden,
36
+ unstable_Scope,
37
+ unstable_getCacheForType,
38
+ unstable_useCacheRefresh,
39
+ unstable_useOpaqueIdentifier,
40
useCallback,
41
useContext,
42
+ useDebugValue,
43
+ useDeferredValue,
44
+ useDeferredValue as unstable_useDeferredValue, // TODO: Remove once call sights updated to useDeferredValue
45
useEffect,
46
useImperativeHandle,
23
- useDebugValue,
47
useLayoutEffect,
48
useMemo,
49
useMutableSource,
50
useMutableSource as unstable_useMutableSource,
28
- createMutableSource,
29
- createMutableSource as unstable_createMutableSource,
51
useReducer,
52
useRef,
53
useState,
33
- Fragment,
34
- Profiler,
35
- StrictMode,
36
- Suspense,
37
- unstable_LegacyHidden,
38
- createElement,
39
- cloneElement,
40
- isValidElement,
41
- version,
42
- __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
43
- // exposeConcurrentModeAPIs
54
useTransition,
45
- useTransition as unstable_useTransition,
46
- useDeferredValue,
47
- useDeferredValue as unstable_useDeferredValue,
48
- startTransition,
49
- startTransition as unstable_startTransition,
50
- SuspenseList,
51
- SuspenseList as unstable_SuspenseList,
52
- unstable_getCacheForType,
53
- unstable_Cache,
54
- unstable_useCacheRefresh,
55
- // enableScopeAPI
56
- unstable_Scope,
57
- unstable_useOpaqueIdentifier,
58
- // enableDebugTracing
59
- unstable_DebugTracingMode,
55
+ useTransition as unstable_useTransition, // TODO: Remove once call sights updated to useTransition
56
+ version,
57
} from './src/React';
58
export {jsx, jsxs, jsxDEV} from './src/jsx/ReactJSX';
packages/react/index.stable.js
+18
-11
@@ -8,32 +8,39 @@
8
*/
9
10
export {
11
+ __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
12
Children,
12
- createRef,
13
Component,
14
+ Fragment,
15
+ Profiler,
16
PureComponent,
17
+ StrictMode,
18
+ Suspense,
19
+ SuspenseList,
20
+ cloneElement,
21
createContext,
22
+ createElement,
23
+ createFactory,
24
+ createMutableSource as unstable_createMutableSource,
25
+ createRef,
26
forwardRef,
27
+ isValidElement,
28
lazy,
29
memo,
30
+ startTransition,
31
+ unstable_useOpaqueIdentifier,
32
useCallback,
33
useContext,
34
+ useDebugValue,
35
+ useDeferredValue,
36
useEffect,
37
useImperativeHandle,
23
- useDebugValue,
38
useLayoutEffect,
39
useMemo,
40
+ useMutableSource as unstable_useMutableSource,
41
useReducer,
42
useRef,
43
useState,
29
- Fragment,
30
- Profiler,
31
- StrictMode,
32
- Suspense,
33
- createElement,
34
- cloneElement,
35
- isValidElement,
44
+ useTransition,
45
version,
37
- __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
38
- createFactory,
46
} from './src/React';
packages/react/src/__tests__/ReactProfiler-test.internal.js
+7
-14
@@ -186,7 +186,6 @@ describe(`onRender`, () => {
186
expect(callback).toHaveBeenCalledTimes(2);
187
});
188
189
- // @gate experimental || !enableSyncDefaultUpdates
189
it('is not invoked until the commit phase', () => {
190
const callback = jest.fn();
191
@@ -196,7 +195,7 @@ describe(`onRender`, () => {
195
};
196
197
if (gate(flags => flags.enableSyncDefaultUpdates)) {
199
- React.unstable_startTransition(() => {
198
+ React.startTransition(() => {
199
ReactTestRenderer.create(
200
<React.Profiler id="test" onRender={callback}>
201
<Yield value="first" />
@@ -690,7 +689,6 @@ describe(`onRender`, () => {
689
expect(onRender.mock.calls[2][1]).toBe('update');
690
});
691
693
- // @gate experimental
692
it('is properly distinguish updates and nested-updates when there is more than sync remaining work', () => {
693
loadModules({
694
useNoopRenderer: true,
@@ -709,7 +707,7 @@ describe(`onRender`, () => {
707
const onRender = jest.fn();
708
709
// Schedule low-priority work.
712
- React.unstable_startTransition(() =>
710
+ React.startTransition(() =>
711
ReactNoop.render(
712
<React.Profiler id="root" onRender={onRender}>
713
<Component />
@@ -734,7 +732,6 @@ describe(`onRender`, () => {
732
});
733
734
describe('with regard to interruptions', () => {
737
- // @gate experimental || !enableSyncDefaultUpdates
735
it('should accumulate actual time after a scheduling interruptions', () => {
736
const callback = jest.fn();
737
@@ -748,7 +745,7 @@ describe(`onRender`, () => {
745
746
// Render partially, but run out of time before completing.
747
if (gate(flags => flags.enableSyncDefaultUpdates)) {
751
- React.unstable_startTransition(() => {
748
+ React.startTransition(() => {
749
ReactTestRenderer.create(
750
<React.Profiler id="test" onRender={callback}>
751
<Yield renderTime={2} />
@@ -781,7 +778,6 @@ describe(`onRender`, () => {
778
expect(call[5]).toBe(10); // commit time
779
});
780
784
- // @gate experimental || !enableSyncDefaultUpdates
781
it('should not include time between frames', () => {
782
const callback = jest.fn();
783
@@ -796,7 +792,7 @@ describe(`onRender`, () => {
792
// Render partially, but don't finish.
793
// This partial render should take 5ms of simulated time.
794
if (gate(flags => flags.enableSyncDefaultUpdates)) {
799
- React.unstable_startTransition(() => {
795
+ React.startTransition(() => {
796
ReactTestRenderer.create(
797
<React.Profiler id="outer" onRender={callback}>
798
<Yield renderTime={5} />
@@ -847,7 +843,6 @@ describe(`onRender`, () => {
843
expect(outerCall[5]).toBe(87); // commit time
844
});
845
850
- // @gate experimental || !enableSyncDefaultUpdates
846
it('should report the expected times when a high-pri update replaces a mount in-progress', () => {
847
const callback = jest.fn();
848
@@ -863,7 +858,7 @@ describe(`onRender`, () => {
858
// This partial render should take 10ms of simulated time.
859
let renderer;
860
if (gate(flags => flags.enableSyncDefaultUpdates)) {
866
- React.unstable_startTransition(() => {
861
+ React.startTransition(() => {
862
renderer = ReactTestRenderer.create(
863
<React.Profiler id="test" onRender={callback}>
864
<Yield renderTime={10} />
@@ -914,7 +909,6 @@ describe(`onRender`, () => {
909
expect(callback).toHaveBeenCalledTimes(0);
910
});
911
917
- // @gate experimental || !enableSyncDefaultUpdates
912
it('should report the expected times when a high-priority update replaces a low-priority update', () => {
913
const callback = jest.fn();
914
@@ -951,7 +945,7 @@ describe(`onRender`, () => {
945
// Render a partially update, but don't finish.
946
// This partial render should take 3ms of simulated time.
947
if (gate(flags => flags.enableSyncDefaultUpdates)) {
954
- React.unstable_startTransition(() => {
948
+ React.startTransition(() => {
949
renderer.update(
950
<React.Profiler id="test" onRender={callback}>
951
<Yield renderTime={3} />
@@ -1008,7 +1002,6 @@ describe(`onRender`, () => {
1002
expect(callback).toHaveBeenCalledTimes(1);
1003
});
1004
1011
- // @gate experimental || !enableSyncDefaultUpdates
1005
it('should report the expected times when a high-priority update interrupts a low-priority update', () => {
1006
const callback = jest.fn();
1007
@@ -1076,7 +1069,7 @@ describe(`onRender`, () => {
1069
// Render a partially update, but don't finish.
1070
// This partial render will take 10ms of actual render time.
1071
if (gate(flags => flags.enableSyncDefaultUpdates)) {
1079
- React.unstable_startTransition(() => {
1072
+ React.startTransition(() => {
1073
first.setState({renderTime: 10});
1074
});
1075
} else {
packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js
+1
-2
@@ -138,7 +138,6 @@ describe('ReactProfiler DevTools integration', () => {
138
).toBe(7);
139
});
140
141
- // @gate experimental || !enableSyncDefaultUpdates
141
it('regression test: #17159', () => {
142
function Text({text}) {
143
Scheduler.unstable_yieldValue(text);
@@ -157,7 +156,7 @@ describe('ReactProfiler DevTools integration', () => {
156
Scheduler.unstable_advanceTime(10000);
157
// Schedule an update.
158
if (gate(flags => flags.enableSyncDefaultUpdates)) {
160
- React.unstable_startTransition(() => {
159
+ React.startTransition(() => {
160
root.update(<Text text="B" />);
161
});
162
} else {
packages/react/src/__tests__/ReactStrictMode-test.internal.js
-4
@@ -49,7 +49,6 @@ describe('ReactStrictMode', () => {
49
return null;
50
}
51
52
- // @gate experimental
52
it('should default to not strict', () => {
53
act(() => {
54
const container = document.createElement('div');
@@ -65,7 +64,6 @@ describe('ReactStrictMode', () => {
64
});
65
66
if (__DEV__) {
68
- // @gate experimental
67
it('should support enabling strict mode via createRoot option', () => {
68
act(() => {
69
const container = document.createElement('div');
@@ -87,7 +85,6 @@ describe('ReactStrictMode', () => {
85
]);
86
});
87
90
- // @gate experimental
88
it('should include legacy + strict effects mode', () => {
89
act(() => {
90
const container = document.createElement('div');
@@ -111,7 +108,6 @@ describe('ReactStrictMode', () => {
108
]);
109
});
110
114
- // @gate experimental
111
it('should allow level to be increased with nesting', () => {
112
act(() => {
113
const container = document.createElement('div');
packages/react/src/__tests__/ReactStrictMode-test.js
+3
-6
@@ -362,7 +362,6 @@ describe('Concurrent Mode', () => {
362
Scheduler = require('scheduler');
363
});
364
365
- // @gate experimental
365
it('should warn about unsafe legacy lifecycle methods anywhere in a StrictMode tree', () => {
366
function StrictRoot() {
367
return (
@@ -405,7 +404,7 @@ describe('Concurrent Mode', () => {
404
}
405
406
const container = document.createElement('div');
408
- const root = ReactDOM.unstable_createRoot(container);
407
+ const root = ReactDOM.createRoot(container);
408
root.render(<StrictRoot />);
409
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
410
[
@@ -436,7 +435,6 @@ Please update the following components: App`,
435
Scheduler.unstable_flushAll();
436
});
437
439
- // @gate experimental
438
it('should coalesce warnings by lifecycle name', () => {
439
function StrictRoot() {
440
return (
@@ -468,7 +466,7 @@ Please update the following components: App`,
466
}
467
468
const container = document.createElement('div');
471
- const root = ReactDOM.unstable_createRoot(container);
469
+ const root = ReactDOM.createRoot(container);
470
root.render(<StrictRoot />);
471
472
expect(() => {
@@ -526,7 +524,6 @@ Please update the following components: Parent`,
524
Scheduler.unstable_flushAll();
525
});
526
529
- // @gate experimental
527
it('should warn about components not present during the initial render', () => {
528
function StrictRoot({foo}) {
529
return <React.StrictMode>{foo ? <Foo /> : <Bar />}</React.StrictMode>;
@@ -545,7 +542,7 @@ Please update the following components: Parent`,
542
}
543
544
const container = document.createElement('div');
548
- const root = ReactDOM.unstable_createRoot(container);
545
+ const root = ReactDOM.createRoot(container);
546
root.render(<StrictRoot foo={true} />);
547
expect(() =>
548
Scheduler.unstable_flushAll(),
packages/react/unstable-shared-subset.experimental.js
+17
-16
@@ -8,31 +8,32 @@
8
*/
9
10
export {
11
+ __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
12
Children,
13
+ Fragment,
14
+ Profiler,
15
+ StrictMode,
16
+ Suspense,
17
+ SuspenseList,
18
+ cloneElement,
19
+ createElement,
20
+ createMutableSource as unstable_createMutableSource,
21
createRef,
22
forwardRef,
23
+ isValidElement,
24
lazy,
25
memo,
26
+ startTransition,
27
+ unstable_DebugTracingMode,
28
+ unstable_getCacheForType,
29
+ unstable_useOpaqueIdentifier,
30
useCallback,
31
useContext,
32
useDebugValue,
33
+ useDeferredValue,
34
+ useDeferredValue as unstable_useDeferredValue,
35
useMemo,
36
useMutableSource as unstable_useMutableSource,
21
- createMutableSource as unstable_createMutableSource,
22
- Fragment,
23
- Profiler,
24
- StrictMode,
25
- Suspense,
26
- createElement,
27
- cloneElement,
28
- isValidElement,
37
+ useTransition,
38
version,
30
- __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
31
- // exposeConcurrentModeAPIs
32
- useDeferredValue as unstable_useDeferredValue,
33
- SuspenseList as unstable_SuspenseList,
34
- unstable_useOpaqueIdentifier,
35
- unstable_getCacheForType,
36
- // enableDebugTracing
37
- unstable_DebugTracingMode,
39
} from './src/React';
packages/shared/ReactFeatureFlags.js
+3
-3
@@ -55,11 +55,11 @@ export const enableProfilerNestedUpdateScheduledHook = false;
55
export const enableUpdaterTracking = __PROFILE__;
56
57
// SSR experiments
58
-export const enableSuspenseServerRenderer = __EXPERIMENTAL__;
59
-export const enableSelectiveHydration = __EXPERIMENTAL__;
58
+export const enableSuspenseServerRenderer = true;
59
+export const enableSelectiveHydration = true;
60
61
// Flight experiments
62
-export const enableLazyElements = __EXPERIMENTAL__;
62
+export const enableLazyElements = true;
63
export const enableCache = __EXPERIMENTAL__;
64
65
// Only used in www builds.
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
+1
-1
@@ -23,7 +23,7 @@ export const enableSuspenseLayoutEffectSemantics = __VARIANT__;
23
// Enable this flag to help with concurrent mode debugging.
24
// It logs information to the console about React scheduling, rendering, and commit phases.
25
//
26
-// NOTE: This feature will only work in DEV mode; all callsights are wrapped with __DEV__.
26
+// NOTE: This feature will only work in DEV mode; all callsites are wrapped with __DEV__.
27
export const enableDebugTracing = __EXPERIMENTAL__;
28
export const enableUpdaterTracking = false;
29
packages/use-subscription/src/__tests__/useSubscription-test.js
+4
-7
@@ -262,7 +262,6 @@ describe('useSubscription', () => {
262
expect(subscriptions).toHaveLength(2);
263
});
264
265
- // @gate experimental || !enableSyncDefaultUpdates
265
it('should ignore values emitted by a new subscribable until the commit phase', () => {
266
const log = [];
267
@@ -333,7 +332,7 @@ describe('useSubscription', () => {
332
// Start React update, but don't finish
333
act(() => {
334
if (gate(flags => flags.enableSyncDefaultUpdates)) {
336
- React.unstable_startTransition(() => {
335
+ React.startTransition(() => {
336
renderer.update(<Parent observed={observableB} />);
337
});
338
} else {
@@ -370,7 +369,6 @@ describe('useSubscription', () => {
369
]);
370
});
371
373
- // @gate experimental || !enableSyncDefaultUpdates
372
it('should not drop values emitted between updates', () => {
373
const log = [];
374
@@ -442,7 +440,7 @@ describe('useSubscription', () => {
440
// Start React update, but don't finish
441
act(() => {
442
if (gate(flags => flags.enableSyncDefaultUpdates)) {
445
- React.unstable_startTransition(() => {
443
+ React.startTransition(() => {
444
renderer.update(<Parent observed={observableB} />);
445
});
446
} else {
@@ -576,7 +574,6 @@ describe('useSubscription', () => {
574
Scheduler.unstable_flushAll();
575
});
576
579
- // @gate experimental || !enableSyncDefaultUpdates
577
it('should not tear if a mutation occurs during a concurrent update', () => {
578
const input = document.createElement('input');
579
@@ -625,7 +622,7 @@ describe('useSubscription', () => {
622
// This update will not be eagerly evaluated,
623
// but useSubscription() should eagerly close over the updated value to avoid tearing.
624
if (gate(flags => flags.enableSyncDefaultUpdates)) {
628
- React.unstable_startTransition(() => {
625
+ React.startTransition(() => {
626
mutate('C');
627
});
628
} else {
@@ -633,7 +630,7 @@ describe('useSubscription', () => {
630
}
631
expect(Scheduler).toFlushAndYieldThrough(['render:first:C']);
632
if (gate(flags => flags.enableSyncDefaultUpdates)) {
636
- React.unstable_startTransition(() => {
633
+ React.startTransition(() => {
634
mutate('D');
635
});
636
} else {