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`
This commit is contained in:
Brian Vaughn 2021-05-12 11:28:14 -04:00 committed by GitHub
parent b8fda6cabc
commit 2bf4805e4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
92 changed files with 575 additions and 969 deletions

View File

@ -268,7 +268,6 @@ describe('createSubscription', () => {
expect(Scheduler).toFlushAndYield(['b-1']);
});
// @gate experimental || !enableSyncDefaultUpdates
it('should ignore values emitted by a new subscribable until the commit phase', () => {
const log = [];
@ -327,7 +326,7 @@ describe('createSubscription', () => {
// Start React update, but don't finish
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Parent observed={observableB} />);
});
} else {
@ -362,7 +361,6 @@ describe('createSubscription', () => {
]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('should not drop values emitted between updates', () => {
const log = [];
@ -421,7 +419,7 @@ describe('createSubscription', () => {
// Start React update, but don't finish
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Parent observed={observableB} />);
});
} else {

View File

@ -366,10 +366,9 @@ describe('ReactHooksInspectionIntegration', () => {
]);
});
// @gate experimental
it('should support composite useTransition hook', () => {
function Foo(props) {
React.unstable_useTransition();
React.useTransition();
const memoizedValue = React.useMemo(() => 'hello', []);
return <div>{memoizedValue}</div>;
}
@ -394,10 +393,9 @@ describe('ReactHooksInspectionIntegration', () => {
]);
});
// @gate experimental
it('should support composite useDeferredValue hook', () => {
function Foo(props) {
React.unstable_useDeferredValue('abc', {
React.useDeferredValue('abc', {
timeoutMs: 500,
});
const [state] = React.useState(() => 'hello', []);
@ -424,7 +422,6 @@ describe('ReactHooksInspectionIntegration', () => {
]);
});
// @gate experimental
it('should support composite useOpaqueIdentifier hook', () => {
function Foo(props) {
const id = React.unstable_useOpaqueIdentifier();
@ -452,7 +449,6 @@ describe('ReactHooksInspectionIntegration', () => {
});
});
// @gate experimental
it('should support composite useOpaqueIdentifier hook in concurrent mode', () => {
function Foo(props) {
const id = React.unstable_useOpaqueIdentifier();
@ -846,37 +842,40 @@ describe('ReactHooksInspectionIntegration', () => {
]);
});
if (__EXPERIMENTAL__) {
it('should support composite useMutableSource hook', () => {
const mutableSource = React.unstable_createMutableSource({}, () => 1);
function Foo(props) {
React.unstable_useMutableSource(
mutableSource,
() => 'snapshot',
() => {},
);
React.useMemo(() => 'memo', []);
return <div />;
}
const renderer = ReactTestRenderer.create(<Foo />);
const childFiber = renderer.root.findByType(Foo)._currentFiber();
const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
expect(tree).toEqual([
{
id: 0,
isStateEditable: false,
name: 'MutableSource',
value: 'snapshot',
subHooks: [],
},
{
id: 1,
isStateEditable: false,
name: 'Memo',
value: 'memo',
subHooks: [],
},
]);
});
}
it('should support composite useMutableSource hook', () => {
const createMutableSource =
React.createMutableSource || React.unstable_createMutableSource;
const useMutableSource =
React.useMutableSource || React.unstable_useMutableSource;
const mutableSource = createMutableSource({}, () => 1);
function Foo(props) {
useMutableSource(
mutableSource,
() => 'snapshot',
() => {},
);
React.useMemo(() => 'memo', []);
return <div />;
}
const renderer = ReactTestRenderer.create(<Foo />);
const childFiber = renderer.root.findByType(Foo)._currentFiber();
const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
expect(tree).toEqual([
{
id: 0,
isStateEditable: false,
name: 'MutableSource',
value: 'snapshot',
subHooks: [],
},
{
id: 1,
isStateEditable: false,
name: 'Memo',
value: 'memo',
subHooks: [],
},
]);
});
});

View File

@ -12,7 +12,7 @@ import {
// $FlowFixMe Flow does not yet know about flushSync()
flushSync,
// $FlowFixMe Flow does not yet know about createRoot()
unstable_createRoot as createRoot,
createRoot,
} from 'react-dom';
import Bridge from 'react-devtools-shared/src/bridge';
import Store from 'react-devtools-shared/src/devtools/store';

View File

@ -1,7 +1,7 @@
/* global chrome */
import {createElement} from 'react';
import {unstable_createRoot as createRoot, flushSync} from 'react-dom';
import {createRoot, flushSync} from 'react-dom';
import Bridge from 'react-devtools-shared/src/bridge';
import Store from 'react-devtools-shared/src/devtools/store';
import {getBrowserName, getBrowserTheme} from './utils';

View File

@ -8,9 +8,11 @@
*/
import {
// $FlowFixMe
unstable_createMutableSource as createMutableSource,
unstable_useMutableSource as useMutableSource,
useLayoutEffect,
// $FlowFixMe
unstable_useMutableSource as useMutableSource,
} from 'react';
import {

View File

@ -382,7 +382,7 @@ describe(preprocessData, () => {
});
});
// @gate experimental && enableSchedulingProfiler
// @gate enableSchedulingProfiler
it('should process a sample createRoot render sequence', () => {
function App() {
const [didMount, setDidMount] = React.useState(false);

View File

@ -11,7 +11,7 @@ import 'regenerator-runtime/runtime';
import * as React from 'react';
// $FlowFixMe Flow does not yet know about createRoot()
import {unstable_createRoot as createRoot} from 'react-dom';
import {createRoot} from 'react-dom';
import nullthrows from 'nullthrows';
import App from './App';

View File

@ -149,7 +149,7 @@ describe('commit tree', () => {
it('should support Lazy components (createRoot)', async () => {
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
utils.act(() => store.profilerStore.startProfiling());
utils.act(() => root.render(<App renderChildren={true} />));
@ -226,7 +226,7 @@ describe('commit tree', () => {
it('should support Lazy components that are unmounted before resolving (createRoot)', async () => {
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
utils.act(() => store.profilerStore.startProfiling());
utils.act(() => root.render(<App renderChildren={true} />));

View File

@ -89,7 +89,7 @@ describe('profiling HostRoot', () => {
utils.act(() => store.profilerStore.startProfiling());
utils.act(() => {
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<App />);
});
utils.act(() => store.profilerStore.stopProfiling());
@ -122,7 +122,7 @@ describe('profiling HostRoot', () => {
}
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
utils.act(() => store.profilerStore.startProfiling());
utils.act(() => root.render(<App />));

View File

@ -356,18 +356,18 @@ describe('Store', () => {
};
const Wrapper = ({shouldSuspense}) => (
<React.Fragment>
<React.unstable_SuspenseList revealOrder="forwards" tail="collapsed">
<React.SuspenseList revealOrder="forwards" tail="collapsed">
<Component key="A" />
<React.Suspense fallback={<Loading />}>
{shouldSuspense ? <SuspendingComponent /> : <Component key="B" />}
</React.Suspense>
<Component key="C" />
</React.unstable_SuspenseList>
</React.SuspenseList>
</React.Fragment>
);
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
act(() => {
root.render(<Wrapper shouldSuspense={true} />);
});
@ -984,7 +984,7 @@ describe('Store', () => {
it('should support Lazy components in (createRoot)', async () => {
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
// Render once to start fetching the lazy component
act(() => root.render(<App renderChildren={true} />));
@ -1020,7 +1020,7 @@ describe('Store', () => {
it('should support Lazy components that are unmounted before they finish loading in (createRoot)', async () => {
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
// Render once to start fetching the lazy component
act(() => root.render(<App renderChildren={true} />));

View File

@ -67,7 +67,7 @@ describe('StoreStressConcurrent', () => {
// 1. Render a normal version of [a, b, c, d, e].
let container = document.createElement('div');
// $FlowFixMe
let root = ReactDOM.unstable_createRoot(container);
let root = ReactDOM.createRoot(container);
act(() => root.render(<Parent>{[a, b, c, d, e]}</Parent>));
expect(store).toMatchInlineSnapshot(
`
@ -151,7 +151,7 @@ describe('StoreStressConcurrent', () => {
// Ensure fresh mount.
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
// Verify mounting 'abcde'.
act(() => root.render(<Parent>{cases[i]}</Parent>));
@ -181,7 +181,7 @@ describe('StoreStressConcurrent', () => {
// There'll be no unmounting until the very end.
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
for (let i = 0; i < cases.length; i++) {
// Verify mounting 'abcde'.
act(() => root.render(<Parent>{cases[i]}</Parent>));
@ -247,7 +247,7 @@ describe('StoreStressConcurrent', () => {
const snapshots = [];
let container = document.createElement('div');
// $FlowFixMe
let root = ReactDOM.unstable_createRoot(container);
let root = ReactDOM.createRoot(container);
for (let i = 0; i < steps.length; i++) {
act(() => root.render(<Root>{steps[i]}</Root>));
// We snapshot each step once so it doesn't regress.
@ -320,7 +320,7 @@ describe('StoreStressConcurrent', () => {
for (let j = 0; j < steps.length; j++) {
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
act(() => root.render(<Root>{steps[i]}</Root>));
expect(print(store)).toMatch(snapshots[i]);
act(() => root.render(<Root>{steps[j]}</Root>));
@ -337,7 +337,7 @@ describe('StoreStressConcurrent', () => {
for (let j = 0; j < steps.length; j++) {
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
act(() =>
root.render(
<Root>
@ -409,7 +409,7 @@ describe('StoreStressConcurrent', () => {
const snapshots = [];
let container = document.createElement('div');
// $FlowFixMe
let root = ReactDOM.unstable_createRoot(container);
let root = ReactDOM.createRoot(container);
for (let i = 0; i < steps.length; i++) {
act(() =>
root.render(
@ -536,7 +536,7 @@ describe('StoreStressConcurrent', () => {
// Always start with a fresh container and steps[i].
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
act(() =>
root.render(
<Root>
@ -582,7 +582,7 @@ describe('StoreStressConcurrent', () => {
// Always start with a fresh container and steps[i].
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
act(() =>
root.render(
<Root>
@ -640,7 +640,7 @@ describe('StoreStressConcurrent', () => {
// Always start with a fresh container and steps[i].
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
act(() =>
root.render(
<Root>
@ -690,7 +690,7 @@ describe('StoreStressConcurrent', () => {
// Always start with a fresh container and steps[i].
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
act(() =>
root.render(
<Root>
@ -744,7 +744,7 @@ describe('StoreStressConcurrent', () => {
// Always start with a fresh container and steps[i].
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
act(() =>
root.render(
<Root>
@ -898,7 +898,7 @@ describe('StoreStressConcurrent', () => {
const snapshots = [];
let container = document.createElement('div');
// $FlowFixMe
let root = ReactDOM.unstable_createRoot(container);
let root = ReactDOM.createRoot(container);
for (let i = 0; i < steps.length; i++) {
act(() =>
root.render(
@ -1055,7 +1055,7 @@ describe('StoreStressConcurrent', () => {
// Always start with a fresh container and steps[i].
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
act(() =>
root.render(
<Root>
@ -1107,7 +1107,7 @@ describe('StoreStressConcurrent', () => {
// Always start with a fresh container and steps[i].
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
act(() =>
root.render(
<Root>
@ -1174,7 +1174,7 @@ describe('StoreStressConcurrent', () => {
// Always start with a fresh container and steps[i].
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
act(() =>
root.render(
<Root>
@ -1226,7 +1226,7 @@ describe('StoreStressConcurrent', () => {
// Always start with a fresh container and steps[i].
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
act(() =>
root.render(
<Root>
@ -1278,7 +1278,7 @@ describe('StoreStressConcurrent', () => {
// Always start with a fresh container and steps[i].
container = document.createElement('div');
// $FlowFixMe
root = ReactDOM.unstable_createRoot(container);
root = ReactDOM.createRoot(container);
act(() =>
root.render(
<Root>

View File

@ -10,7 +10,7 @@
import * as React from 'react';
import {
createContext,
unstable_startTransition as startTransition,
startTransition,
unstable_useCacheRefresh as useCacheRefresh,
useCallback,
useContext,

View File

@ -11,7 +11,7 @@ import * as React from 'react';
import {
useContext,
unstable_useCacheRefresh as useCacheRefresh,
unstable_useTransition as useTransition,
useTransition,
} from 'react';
import Button from '../Button';
import ButtonIcon from '../ButtonIcon';

View File

@ -8,12 +8,7 @@
*/
import * as React from 'react';
import {
unstable_useTransition as useTransition,
useContext,
useRef,
useState,
} from 'react';
import {useTransition, useContext, useRef, useState} from 'react';
import EditableName from './EditableName';
import EditableValue from './EditableValue';
import NewArrayValue from './NewArrayValue';

View File

@ -34,7 +34,7 @@ import {
useMemo,
useReducer,
useRef,
unstable_startTransition as startTransition,
startTransition,
} from 'react';
import {createRegExp} from '../utils';
import {BridgeContext, StoreContext} from '../context';

View File

@ -10,7 +10,7 @@
import type {Wakeable} from 'shared/ReactTypes';
import type {GitHubIssue} from './githubAPI';
import {unstable_getCacheForType} from 'react';
import {unstable_getCacheForType as getCacheForType} from 'react';
import {searchGitHubIssues} from './githubAPI';
const API_TIMEOUT = 3000;
@ -55,7 +55,7 @@ function createMap(): GitHubIssueMap {
}
function getRecordMap(): Map<string, Record<GitHubIssue>> {
return unstable_getCacheForType(createMap);
return getCacheForType(createMap);
}
export function findGitHubIssue(errorMessage: string): GitHubIssue | null {

View File

@ -8,8 +8,8 @@
*/
import {
unstable_getCacheForType,
unstable_startTransition as startTransition,
unstable_getCacheForType as getCacheForType,
startTransition,
} from 'react';
import Store from './devtools/store';
import {inspectElement as inspectElementMutableSource} from './inspectedElementMutableSource';
@ -60,7 +60,7 @@ function createMap(): InspectedElementMap {
}
function getRecordMap(): WeakMap<Element, Record<InspectedElementFrontend>> {
return unstable_getCacheForType(createMap);
return getCacheForType(createMap);
}
function createCacheSeed(

View File

@ -8,12 +8,7 @@
*/
import * as React from 'react';
import {
Fragment,
Suspense,
unstable_SuspenseList as SuspenseList,
useState,
} from 'react';
import {Fragment, Suspense, SuspenseList, useState} from 'react';
function SuspenseTree() {
return (

View File

@ -5,7 +5,7 @@
import {createElement} from 'react';
import {
// $FlowFixMe Flow does not yet know about createRoot()
unstable_createRoot as createRoot,
createRoot,
} from 'react-dom';
import DeeplyNestedComponents from './DeeplyNestedComponents';
import Iframe from './Iframe';

View File

@ -2,7 +2,7 @@
import {createElement} from 'react';
// $FlowFixMe Flow does not yet know about createRoot()
import {unstable_createRoot as createRoot} from 'react-dom';
import {createRoot} from 'react-dom';
import {
activate as activateBackend,
initialize as initializeBackend,

View File

@ -19,22 +19,21 @@ Object.assign((__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: any), {
});
export {
createPortal,
unstable_batchedUpdates,
flushSync,
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
version,
createPortal,
createRoot,
createRoot as unstable_createRoot, // TODO Remove once callsites use createRoot
findDOMNode,
flushSync,
hydrate,
render,
unmountComponentAtNode,
createRoot,
createRoot as unstable_createRoot,
unstable_flushControlled,
unstable_scheduleHydration,
unstable_runWithPriority,
unstable_renderSubtreeIntoContainer,
unstable_createPortal,
unstable_batchedUpdates,
unstable_createEventHandle,
unstable_flushControlled,
unstable_isNewReconciler,
unstable_renderSubtreeIntoContainer,
unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority.
unstable_scheduleHydration,
version,
} from './src/client/ReactDOM';

View File

@ -8,26 +8,18 @@
*/
export {
createPortal,
unstable_batchedUpdates,
flushSync,
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
version,
// Disabled behind disableLegacyReactDOMAPIs
createPortal,
createRoot,
findDOMNode,
flushSync,
hydrate,
render,
unmountComponentAtNode,
// exposeConcurrentModeAPIs
createRoot as unstable_createRoot,
unstable_batchedUpdates,
unstable_flushControlled,
unstable_scheduleHydration,
// DO NOT USE: Temporarily exposing this to migrate off of Scheduler.runWithPriority.
unstable_runWithPriority,
// Disabled behind disableUnstableRenderSubtreeIntoContainer
unstable_renderSubtreeIntoContainer,
// Disabled behind disableUnstableCreatePortal
// Temporary alias since we already shipped React 16 RC with it.
// TODO: remove in React 18.
unstable_createPortal,
unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority.
unstable_scheduleHydration,
version,
} from './src/client/ReactDOM';

View File

@ -10,22 +10,21 @@
// Export all exports so that they're available in tests.
// We can't use export * from in Flow for some reason.
export {
createPortal,
unstable_batchedUpdates,
flushSync,
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
version,
createPortal,
createRoot,
createRoot as unstable_createRoot,
findDOMNode,
flushSync,
hydrate,
render,
unmountComponentAtNode,
createRoot,
createRoot as unstable_createRoot,
unstable_flushControlled,
unstable_scheduleHydration,
unstable_runWithPriority,
unstable_renderSubtreeIntoContainer,
unstable_createPortal,
unstable_batchedUpdates,
unstable_createEventHandle,
unstable_flushControlled,
unstable_isNewReconciler,
unstable_renderSubtreeIntoContainer,
unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority.
unstable_scheduleHydration,
version,
} from './src/client/ReactDOM';

View File

@ -8,16 +8,16 @@
*/
export {
createPortal,
unstable_batchedUpdates,
flushSync,
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
version,
createPortal,
createRoot,
createRoot as unstable_createRoot,
unstable_flushControlled,
unstable_scheduleHydration,
unstable_runWithPriority,
createRoot as unstable_createRoot, // TODO Remove once callsites use createRoot
flushSync,
unstable_batchedUpdates,
unstable_createEventHandle,
unstable_flushControlled,
unstable_isNewReconciler,
unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority.
unstable_scheduleHydration,
version,
} from './src/client/ReactDOM';

View File

@ -8,17 +8,15 @@
*/
export {
createPortal,
unstable_batchedUpdates,
flushSync,
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
version,
createPortal,
createRoot,
findDOMNode,
flushSync,
hydrate,
render,
unmountComponentAtNode,
unstable_batchedUpdates,
unstable_renderSubtreeIntoContainer,
// Temporary alias since we already shipped React 16 RC with it.
// TODO: remove in React 18.
unstable_createPortal,
version,
} from './src/client/ReactDOM';

View File

@ -246,34 +246,6 @@ describe('ReactDOMFiber', () => {
expect(container.innerHTML).toBe('');
});
// TODO: remove in React 18
if (!__EXPERIMENTAL__) {
it('should support unstable_createPortal alias', () => {
const portalContainer = document.createElement('div');
expect(() =>
ReactDOM.render(
<div>
{ReactDOM.unstable_createPortal(<div>portal</div>, portalContainer)}
</div>,
container,
),
).toWarnDev(
'The ReactDOM.unstable_createPortal() alias has been deprecated, ' +
'and will be removed in React 18+. Update your code to use ' +
'ReactDOM.createPortal() instead. It has the exact same API, ' +
'but without the "unstable_" prefix.',
{withoutStack: true},
);
expect(portalContainer.innerHTML).toBe('<div>portal</div>');
expect(container.innerHTML).toBe('<div></div>');
ReactDOM.unmountComponentAtNode(container);
expect(portalContainer.innerHTML).toBe('');
expect(container.innerHTML).toBe('');
});
}
it('should render many portals', () => {
const portalContainer1 = document.createElement('div');
const portalContainer2 = document.createElement('div');

View File

@ -148,7 +148,6 @@ describe('ReactDOMFiberAsync', () => {
});
describe('concurrent mode', () => {
// @gate experimental
it('does not perform deferred updates synchronously', () => {
const inputRef = React.createRef();
const asyncValueRef = React.createRef();
@ -185,7 +184,7 @@ describe('ReactDOMFiberAsync', () => {
);
}
}
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<Counter />);
Scheduler.unstable_flushAll();
expect(asyncValueRef.current.textContent).toBe('');
@ -204,9 +203,8 @@ describe('ReactDOMFiberAsync', () => {
expect(syncValueRef.current.textContent).toBe('hello');
});
// @gate experimental
it('top-level updates are concurrent', () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<div>Hi</div>);
expect(container.textContent).toEqual('');
Scheduler.unstable_flushAll();
@ -218,7 +216,6 @@ describe('ReactDOMFiberAsync', () => {
expect(container.textContent).toEqual('Bye');
});
// @gate experimental
it('deep updates (setState) are concurrent', () => {
let instance;
class Component extends React.Component {
@ -229,7 +226,7 @@ describe('ReactDOMFiberAsync', () => {
}
}
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<Component />);
expect(container.textContent).toEqual('');
Scheduler.unstable_flushAll();
@ -241,7 +238,6 @@ describe('ReactDOMFiberAsync', () => {
expect(container.textContent).toEqual('1');
});
// @gate experimental
it('flushSync flushes updates before end of the tick', () => {
const ops = [];
let instance;
@ -260,7 +256,7 @@ describe('ReactDOMFiberAsync', () => {
}
}
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<Component />);
Scheduler.unstable_flushAll();
@ -302,7 +298,7 @@ describe('ReactDOMFiberAsync', () => {
return this.state.counter;
}
}
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<Counter />);
Scheduler.unstable_flushAll();
expect(container.textContent).toEqual('0');
@ -385,7 +381,6 @@ describe('ReactDOMFiberAsync', () => {
expect(returnValue).toBe(undefined);
});
// @gate experimental
it('ignores discrete events on a pending removed element', async () => {
const disableButtonRef = React.createRef();
const submitButtonRef = React.createRef();
@ -406,7 +401,7 @@ describe('ReactDOMFiberAsync', () => {
);
}
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
await act(async () => {
root.render(<Form />);
});
@ -426,7 +421,6 @@ describe('ReactDOMFiberAsync', () => {
expect(submitButton.current).toBe(undefined);
});
// @gate experimental
it('ignores discrete events on a pending removed event listener', async () => {
const disableButtonRef = React.createRef();
const submitButtonRef = React.createRef();
@ -458,7 +452,7 @@ describe('ReactDOMFiberAsync', () => {
);
}
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
await act(async () => {
root.render(<Form />);
});
@ -491,7 +485,6 @@ describe('ReactDOMFiberAsync', () => {
expect(formSubmitted).toBe(false);
});
// @gate experimental
it('uses the newest discrete events on a pending changed event listener', async () => {
const enableButtonRef = React.createRef();
const submitButtonRef = React.createRef();
@ -518,7 +511,7 @@ describe('ReactDOMFiberAsync', () => {
);
}
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
await act(async () => {
root.render(<Form />);
});
@ -582,9 +575,8 @@ describe('ReactDOMFiberAsync', () => {
expect(containerC.textContent).toEqual('Finished');
});
// @gate experimental
it('updates flush without yielding in the next event', () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
function Text(props) {
Scheduler.unstable_yieldValue(props.text);
@ -607,7 +599,6 @@ describe('ReactDOMFiberAsync', () => {
expect(container.textContent).toEqual('ABC');
});
// @gate experimental
it('unmounted roots should never clear newer root content from a container', () => {
const ref = React.createRef();
@ -630,7 +621,7 @@ describe('ReactDOMFiberAsync', () => {
return <button ref={ref}>new</button>;
}
const oldRoot = ReactDOM.unstable_createRoot(container);
const oldRoot = ReactDOM.createRoot(container);
act(() => {
oldRoot.render(<OldApp />);
});
@ -642,7 +633,7 @@ describe('ReactDOMFiberAsync', () => {
expect(container.textContent).toBe('');
// We can now render a new one.
const newRoot = ReactDOM.unstable_createRoot(container);
const newRoot = ReactDOM.createRoot(container);
ReactDOM.flushSync(() => {
newRoot.render(<NewApp />);
});

View File

@ -38,7 +38,7 @@ describe('ReactDOMFizzServer', () => {
}
Stream = require('stream');
Suspense = React.Suspense;
SuspenseList = React.unstable_SuspenseList;
SuspenseList = React.SuspenseList;
PropTypes = require('prop-types');
textCache = new Map();
@ -313,7 +313,7 @@ describe('ReactDOMFizzServer', () => {
expect(loggedErrors).toEqual([]);
// Attempt to hydrate the content.
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
root.render(<App isClient={true} />);
Scheduler.unstable_flushAll();
@ -405,7 +405,7 @@ describe('ReactDOMFizzServer', () => {
expect(loggedErrors).toEqual([]);
// Attempt to hydrate the content.
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
root.render(<App isClient={true} />);
Scheduler.unstable_flushAll();
@ -481,7 +481,7 @@ describe('ReactDOMFizzServer', () => {
expect(getVisibleChildren(container)).toEqual(<div>Loading...</div>);
// Attempt to hydrate the content.
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
root.render(<App />);
Scheduler.unstable_flushAll();
@ -563,7 +563,7 @@ describe('ReactDOMFizzServer', () => {
expect(loggedErrors).toEqual([]);
// Attempt to hydrate the content.
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
root.render(<App />);
Scheduler.unstable_flushAll();
@ -635,7 +635,7 @@ describe('ReactDOMFizzServer', () => {
startWriting();
});
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
root.render(<App showMore={false} />);
Scheduler.unstable_flushAll();
@ -703,7 +703,7 @@ describe('ReactDOMFizzServer', () => {
// We're still showing a fallback.
// Attempt to hydrate the content.
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
root.render(<App />);
Scheduler.unstable_flushAll();
@ -1294,7 +1294,7 @@ describe('ReactDOMFizzServer', () => {
// We're still showing a fallback.
// Attempt to hydrate the content.
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
root.render(<App isClient={true} />);
Scheduler.unstable_flushAll();

View File

@ -107,7 +107,6 @@ describe('ReactDOMHooks', () => {
expect(labelRef.current.innerHTML).toBe('abc');
});
// @gate experimental
it('should not bail out when an update is scheduled from within an event handler in Concurrent Mode', async () => {
const {createRef, useCallback, useState} = React;
@ -128,7 +127,7 @@ describe('ReactDOMHooks', () => {
const inputRef = createRef();
const labelRef = createRef();
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<Example inputRef={inputRef} labelRef={labelRef} />);
Scheduler.unstable_flushAll();

View File

@ -42,7 +42,6 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
}
}
// @gate experimental
it('ignores discrete events on a pending removed element', async () => {
const disableButtonRef = React.createRef();
const submitButtonRef = React.createRef();
@ -66,7 +65,7 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
);
}
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
await act(() => {
root.render(<Form />);
});
@ -88,7 +87,6 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
// We'll assume that the browser won't let the user click it.
});
// @gate experimental
it('ignores discrete events on a pending removed event listener', async () => {
const disableButtonRef = React.createRef();
const submitButtonRef = React.createRef();
@ -125,7 +123,7 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
);
}
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<Form />);
// Flush
Scheduler.unstable_flushAll();
@ -157,7 +155,6 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
expect(formSubmitted).toBe(false);
});
// @gate experimental
it('uses the newest discrete events on a pending changed event listener', async () => {
const enableButtonRef = React.createRef();
const submitButtonRef = React.createRef();
@ -188,7 +185,7 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
);
}
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<Form />);
// Flush
Scheduler.unstable_flushAll();
@ -220,9 +217,8 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
expect(formSubmitted).toBe(true);
});
// @gate experimental
it('mouse over should be user-blocking but not discrete', async () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
const target = React.createRef(null);
function Foo() {
@ -251,9 +247,8 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
expect(container.textContent).toEqual('hovered');
});
// @gate experimental
it('mouse enter should be user-blocking but not discrete', async () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
const target = React.createRef(null);
function Foo() {
@ -284,9 +279,8 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
expect(container.textContent).toEqual('hovered');
});
// @gate experimental
it('continuous native events flush as expected', async () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
const target = React.createRef(null);
function Foo({hovered}) {
@ -324,9 +318,8 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
expect(container.textContent).toEqual('hovered');
});
// @gate experimental
it('should batch inside native events', async () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
const target = React.createRef(null);
function Foo() {
@ -375,9 +368,8 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
}
});
// @gate experimental
it('should not flush discrete events at the end of outermost batchedUpdates', async () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
let target;
function Foo() {

View File

@ -27,7 +27,6 @@ describe('ReactDOMNestedEvents', () => {
useState = React.useState;
});
// @gate experimental
test('nested event dispatches should not cause updates to flush', async () => {
const buttonRef = React.createRef(null);
function App() {
@ -58,7 +57,7 @@ describe('ReactDOMNestedEvents', () => {
const container = document.createElement('div');
document.body.appendChild(container);
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
await act(async () => {
root.render(<App />);

View File

@ -28,15 +28,8 @@ describe('ReactDOMRoot', () => {
act = require('react-dom/test-utils').unstable_concurrentAct;
});
if (!__EXPERIMENTAL__) {
it('createRoot is not exposed in stable build', () => {
expect(ReactDOM.unstable_createRoot).toBe(undefined);
});
return;
}
it('renders children', () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<div>Hi</div>);
Scheduler.unstable_flushAll();
expect(container.textContent).toEqual('Hi');
@ -44,7 +37,7 @@ describe('ReactDOMRoot', () => {
it('warns if a callback parameter is provided to render', () => {
const callback = jest.fn();
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
expect(() =>
root.render(<div>Hi</div>, callback),
).toErrorDev(
@ -58,7 +51,7 @@ describe('ReactDOMRoot', () => {
it('warns if a callback parameter is provided to unmount', () => {
const callback = jest.fn();
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<div>Hi</div>);
expect(() =>
root.unmount(callback),
@ -72,7 +65,7 @@ describe('ReactDOMRoot', () => {
});
it('unmounts children', () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<div>Hi</div>);
Scheduler.unstable_flushAll();
expect(container.textContent).toEqual('Hi');
@ -95,7 +88,7 @@ describe('ReactDOMRoot', () => {
// Does not hydrate by default
const container1 = document.createElement('div');
container1.innerHTML = markup;
const root1 = ReactDOM.unstable_createRoot(container1);
const root1 = ReactDOM.createRoot(container1);
root1.render(
<div>
<span />
@ -106,7 +99,7 @@ describe('ReactDOMRoot', () => {
// Accepts `hydrate` option
const container2 = document.createElement('div');
container2.innerHTML = markup;
const root2 = ReactDOM.unstable_createRoot(container2, {hydrate: true});
const root2 = ReactDOM.createRoot(container2, {hydrate: true});
root2.render(
<div>
<span />
@ -138,7 +131,7 @@ describe('ReactDOMRoot', () => {
it('clears existing children', async () => {
container.innerHTML = '<div>a</div><div>b</div>';
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(
<div>
<span>c</span>
@ -159,12 +152,12 @@ describe('ReactDOMRoot', () => {
it('throws a good message on invalid containers', () => {
expect(() => {
ReactDOM.unstable_createRoot(<div>Hi</div>);
ReactDOM.createRoot(<div>Hi</div>);
}).toThrow('createRoot(...): Target container is not a DOM element.');
});
it('warns when rendering with legacy API into createRoot() container', () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<div>Hi</div>);
Scheduler.unstable_flushAll();
expect(container.textContent).toEqual('Hi');
@ -187,7 +180,7 @@ describe('ReactDOMRoot', () => {
});
it('warns when hydrating with legacy API into createRoot() container', () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<div>Hi</div>);
Scheduler.unstable_flushAll();
expect(container.textContent).toEqual('Hi');
@ -207,7 +200,7 @@ describe('ReactDOMRoot', () => {
});
it('warns when unmounting with legacy API (no previous content)', () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<div>Hi</div>);
Scheduler.unstable_flushAll();
expect(container.textContent).toEqual('Hi');
@ -236,7 +229,7 @@ describe('ReactDOMRoot', () => {
// Currently createRoot().render() doesn't clear this.
container.appendChild(document.createElement('div'));
// The rest is the same as test above.
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<div>Hi</div>);
Scheduler.unstable_flushAll();
expect(container.textContent).toEqual('Hi');
@ -262,7 +255,7 @@ describe('ReactDOMRoot', () => {
it('warns when passing legacy container to createRoot()', () => {
ReactDOM.render(<div>Hi</div>, container);
expect(() => {
ReactDOM.unstable_createRoot(container);
ReactDOM.createRoot(container);
}).toErrorDev(
'You are calling ReactDOM.createRoot() on a container that was previously ' +
'passed to ReactDOM.render(). This is not supported.',
@ -271,9 +264,9 @@ describe('ReactDOMRoot', () => {
});
it('warns when creating two roots managing the same container', () => {
ReactDOM.unstable_createRoot(container);
ReactDOM.createRoot(container);
expect(() => {
ReactDOM.unstable_createRoot(container);
ReactDOM.createRoot(container);
}).toErrorDev(
'You are calling ReactDOM.createRoot() on a container that ' +
'has already been passed to createRoot() before. Instead, call ' +
@ -283,15 +276,15 @@ describe('ReactDOMRoot', () => {
});
it('does not warn when creating second root after first one is unmounted', () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.unmount();
Scheduler.unstable_flushAll();
ReactDOM.unstable_createRoot(container); // No warning
ReactDOM.createRoot(container); // No warning
});
it('warns if creating a root on the document.body', async () => {
expect(() => {
ReactDOM.unstable_createRoot(document.body);
ReactDOM.createRoot(document.body);
}).toErrorDev(
'createRoot(): Creating roots directly with document.body is ' +
'discouraged, since its children are often manipulated by third-party ' +
@ -303,7 +296,7 @@ describe('ReactDOMRoot', () => {
});
it('warns if updating a root that has had its contents removed', async () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<div>Hi</div>);
Scheduler.unstable_flushAll();
container.innerHTML = '';
@ -319,9 +312,8 @@ describe('ReactDOMRoot', () => {
);
});
// @gate experimental
it('opts-in to concurrent default updates', async () => {
const root = ReactDOM.unstable_createRoot(container, {
const root = ReactDOM.createRoot(container, {
unstable_concurrentUpdatesByDefault: true,
});

View File

@ -895,7 +895,6 @@ describe('ReactDOMServerHooks', () => {
});
describe('useOpaqueIdentifier', () => {
// @gate experimental
it('generates unique ids for server string render', async () => {
function App(props) {
const idOne = useOpaqueIdentifier();
@ -929,7 +928,6 @@ describe('ReactDOMServerHooks', () => {
).not.toBeNull();
});
// @gate experimental
it('generates unique ids for server stream render', async () => {
function App(props) {
const idOne = useOpaqueIdentifier();
@ -963,7 +961,6 @@ describe('ReactDOMServerHooks', () => {
).not.toBeNull();
});
// @gate experimental
it('generates unique ids for client render', async () => {
function App(props) {
const idOne = useOpaqueIdentifier();
@ -997,7 +994,6 @@ describe('ReactDOMServerHooks', () => {
).not.toBeNull();
});
// @gate experimental
it('generates unique ids for client render on good server markup', async () => {
function App(props) {
const idOne = useOpaqueIdentifier();
@ -1031,7 +1027,6 @@ describe('ReactDOMServerHooks', () => {
).not.toBeNull();
});
// @gate experimental
it('useOpaqueIdentifier does not change id even if the component updates during client render', async () => {
let _setShowId;
function App() {
@ -1063,7 +1058,6 @@ describe('ReactDOMServerHooks', () => {
);
});
// @gate experimental
it('useOpaqueIdentifier identifierPrefix works for server renderer and does not clash', async () => {
function ChildTwo({id}) {
return <div id={id}>Child Three</div>;
@ -1149,7 +1143,6 @@ describe('ReactDOMServerHooks', () => {
).toBe(true);
});
// @gate experimental
it('useOpaqueIdentifier identifierPrefix works for multiple reads on a streaming server renderer', async () => {
function ChildTwo() {
const id = useOpaqueIdentifier();
@ -1241,7 +1234,6 @@ describe('ReactDOMServerHooks', () => {
await Promise.all([streamOneIsDone, streamTwoIsDone]);
});
// @gate experimental
it('useOpaqueIdentifier: IDs match when, after hydration, a new component that uses the ID is rendered', async () => {
let _setShowDiv;
function App() {
@ -1261,7 +1253,7 @@ describe('ReactDOMServerHooks', () => {
document.body.append(container);
container.innerHTML = ReactDOMServer.renderToString(<App />);
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
root.render(<App />);
Scheduler.unstable_flushAll();
jest.runAllTimers();
@ -1285,7 +1277,6 @@ describe('ReactDOMServerHooks', () => {
).not.toBeNull();
});
// @gate experimental
it('useOpaqueIdentifier: IDs match when, after hydration, a new component that uses the ID is rendered for legacy', async () => {
let _setShowDiv;
function App() {
@ -1326,7 +1317,6 @@ describe('ReactDOMServerHooks', () => {
).not.toBeNull();
});
// @gate experimental
it('useOpaqueIdentifier: ID is not used during hydration but is used in an update', async () => {
let _setShow;
function App({unused}) {
@ -1344,7 +1334,7 @@ describe('ReactDOMServerHooks', () => {
const container = document.createElement('div');
document.body.append(container);
container.innerHTML = ReactDOMServer.renderToString(<App />);
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
act(() => {
root.render(<App />);
});
@ -1359,7 +1349,6 @@ describe('ReactDOMServerHooks', () => {
).not.toBeNull();
});
// @gate experimental
it('useOpaqueIdentifier: ID is not used during hydration but is used in an update in legacy', async () => {
let _setShow;
function App({unused}) {
@ -1389,7 +1378,6 @@ describe('ReactDOMServerHooks', () => {
).not.toBeNull();
});
// @gate experimental
it('useOpaqueIdentifier: flushSync', async () => {
let _setShow;
function App() {
@ -1406,7 +1394,7 @@ describe('ReactDOMServerHooks', () => {
const container = document.createElement('div');
document.body.append(container);
container.innerHTML = ReactDOMServer.renderToString(<App />);
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
act(() => {
root.render(<App />);
});
@ -1422,7 +1410,6 @@ describe('ReactDOMServerHooks', () => {
).not.toBeNull();
});
// @gate experimental
it('useOpaqueIdentifier: children with id hydrates before other children if ID updates', async () => {
let _setShow;
@ -1498,7 +1485,7 @@ describe('ReactDOMServerHooks', () => {
.getAttribute('id');
expect(serverId).not.toBeNull();
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
root.render(<App show={false} />);
expect(Scheduler).toHaveYielded([]);
@ -1546,7 +1533,6 @@ describe('ReactDOMServerHooks', () => {
expect(Scheduler).toHaveYielded([]);
});
// @gate experimental
it('useOpaqueIdentifier: IDs match when part of the DOM tree is server rendered and part is client rendered', async () => {
let suspend = true;
let resolve;
@ -1591,7 +1577,7 @@ describe('ReactDOMServerHooks', () => {
container.innerHTML = ReactDOMServer.renderToString(<App />);
suspend = true;
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
await act(async () => {
root.render(<App />);
});
@ -1627,7 +1613,6 @@ describe('ReactDOMServerHooks', () => {
).not.toBeNull();
});
// @gate experimental
it('useOpaqueIdentifier warn when there is a hydration error', async () => {
function Child({appId}) {
return <div aria-labelledby={appId} />;
@ -1642,7 +1627,7 @@ describe('ReactDOMServerHooks', () => {
// This is the wrong HTML string
container.innerHTML = '<span></span>';
ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
[
'Warning: An error occurred during hydration. The server HTML was replaced with client content in <div>.',
@ -1652,7 +1637,6 @@ describe('ReactDOMServerHooks', () => {
);
});
// @gate experimental
it('useOpaqueIdentifier: IDs match when part of the DOM tree is server rendered and part is client rendered', async () => {
let suspend = true;
@ -1695,7 +1679,7 @@ describe('ReactDOMServerHooks', () => {
container.innerHTML = ReactDOMServer.renderToString(<App />);
suspend = false;
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
await act(async () => {
root.render(<App />);
});
@ -1717,7 +1701,6 @@ describe('ReactDOMServerHooks', () => {
).not.toBeNull();
});
// @gate experimental
it('useOpaqueIdentifier warn when there is a hydration error', async () => {
function Child({appId}) {
return <div aria-labelledby={appId} />;
@ -1732,7 +1715,7 @@ describe('ReactDOMServerHooks', () => {
// This is the wrong HTML string
container.innerHTML = '<span></span>';
ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
[
'Warning: An error occurred during hydration. The server HTML was replaced with client content in <div>.',
@ -1742,7 +1725,6 @@ describe('ReactDOMServerHooks', () => {
);
});
// @gate experimental
it('useOpaqueIdentifier warns when there is a hydration error and we are using ID as a string', async () => {
function Child({appId}) {
return <div aria-labelledby={appId + ''} />;
@ -1757,7 +1739,7 @@ describe('ReactDOMServerHooks', () => {
// This is the wrong HTML string
container.innerHTML = '<span></span>';
ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
[
'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', () => {
);
});
// @gate experimental
it('useOpaqueIdentifier warns when there is a hydration error and we are using ID as a string', async () => {
function Child({appId}) {
return <div aria-labelledby={appId + ''} />;
@ -1782,7 +1763,7 @@ describe('ReactDOMServerHooks', () => {
// This is the wrong HTML string
container.innerHTML = '<span></span>';
ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
[
'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', () => {
);
});
// @gate experimental
it('useOpaqueIdentifier warns if you try to use the result as a string in a child component', async () => {
function Child({appId}) {
return <div aria-labelledby={appId + ''} />;
@ -1806,7 +1786,7 @@ describe('ReactDOMServerHooks', () => {
document.body.appendChild(container);
container.innerHTML = ReactDOMServer.renderToString(<App />);
ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
[
'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', () => {
);
});
// @gate experimental
it('useOpaqueIdentifier warns if you try to use the result as a string', async () => {
function App() {
const id = useOpaqueIdentifier();
@ -1827,7 +1806,7 @@ describe('ReactDOMServerHooks', () => {
document.body.appendChild(container);
container.innerHTML = ReactDOMServer.renderToString(<App />);
ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
[
'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', () => {
);
});
// @gate experimental
it('useOpaqueIdentifier warns if you try to use the result as a string in a child component wrapped in a Suspense', async () => {
function Child({appId}) {
return <div aria-labelledby={appId + ''} />;
@ -1856,7 +1834,7 @@ describe('ReactDOMServerHooks', () => {
container.innerHTML = ReactDOMServer.renderToString(<App />);
ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
if (gate(flags => flags.deferRenderPhaseUpdateToNextBatch)) {
expect(() => Scheduler.unstable_flushAll()).toErrorDev([
@ -1878,7 +1856,6 @@ describe('ReactDOMServerHooks', () => {
}
});
// @gate experimental
it('useOpaqueIdentifier warns if you try to add the result as a number in a child component wrapped in a Suspense', async () => {
function Child({appId}) {
return <div aria-labelledby={+appId} />;
@ -1899,7 +1876,7 @@ describe('ReactDOMServerHooks', () => {
container.innerHTML = ReactDOMServer.renderToString(<App />);
ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
if (gate(flags => flags.deferRenderPhaseUpdateToNextBatch)) {
expect(() => Scheduler.unstable_flushAll()).toErrorDev([
@ -1921,7 +1898,6 @@ describe('ReactDOMServerHooks', () => {
}
});
// @gate experimental
it('useOpaqueIdentifier with two opaque identifiers on the same page', () => {
let _setShow;
@ -1960,7 +1936,7 @@ describe('ReactDOMServerHooks', () => {
.getAttribute('aria-labelledby'),
).toEqual(serverID);
ReactDOM.unstable_createRoot(container, {hydrate: true}).render(<App />);
ReactDOM.createRoot(container, {hydrate: true}).render(<App />);
jest.runAllTimers();
expect(Scheduler).toHaveYielded([]);
expect(Scheduler).toFlushAndYield([]);

View File

@ -102,7 +102,6 @@ describe('ReactDOMServerPartialHydration', () => {
);
}
// @gate experimental
it('hydrates a parent even if a child Suspense boundary is blocked', async () => {
let suspend = false;
let resolve;
@ -161,7 +160,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(ref.current).toBe(span);
});
// @gate experimental
it('calls the hydration callbacks after hydration or deletion', async () => {
let suspend = false;
let resolve;
@ -252,7 +250,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(deleted.length).toBe(1);
});
// @gate experimental
it('calls the onDeleted hydration callback if the parent gets deleted', async () => {
let suspend = false;
const promise = new Promise(() => {});
@ -310,7 +307,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(deleted.length).toBe(1);
});
// @gate experimental || www
it('warns and replaces the boundary content in legacy mode', async () => {
let suspend = false;
let resolve;
@ -390,7 +386,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(container.textContent).toBe('Hello');
});
// @gate experimental
it('can insert siblings before the dehydrated boundary', () => {
let suspend = false;
const promise = new Promise(() => {});
@ -449,7 +444,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(container.firstChild.firstChild.textContent).toBe('First');
});
// @gate experimental
it('can delete the dehydrated boundary before it is hydrated', () => {
let suspend = false;
const promise = new Promise(() => {});
@ -506,7 +500,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(container.firstChild.children[1].textContent).toBe('After');
});
// @gate experimental
it('blocks updates to hydrate the content first if props have changed', async () => {
let suspend = false;
let resolve;
@ -652,7 +645,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(span.className).toBe('hi');
});
// @gate experimental
it('shows the fallback if props have changed before hydration completes and is still suspended', async () => {
let suspend = false;
let resolve;
@ -722,7 +714,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(container.textContent).toBe('Hi');
});
// @gate experimental
it('shows the fallback of the outer if fallback is missing', async () => {
// This is the same exact test as above but with a nested Suspense without a fallback.
// This should be a noop.
@ -796,7 +787,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(container.textContent).toBe('Hi');
});
// @gate experimental
it('clears nested suspense boundaries if they did not hydrate yet', async () => {
let suspend = false;
let resolve;
@ -869,7 +859,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(container.textContent).toBe('Hi Hi');
});
// @gate experimental
it('hydrates first if props changed but we are able to resolve within a timeout', async () => {
let suspend = false;
let resolve;
@ -917,9 +906,7 @@ describe('ReactDOMServerPartialHydration', () => {
expect(container.textContent).toBe('Hello');
// Render an update with a long timeout.
React.unstable_startTransition(() =>
root.render(<App text="Hi" className="hi" />),
);
React.startTransition(() => root.render(<App text="Hi" className="hi" />));
// This shouldn't force the fallback yet.
Scheduler.unstable_flushAll();
@ -949,7 +936,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(span.className).toBe('hi');
});
// @gate experimental
it('warns but works if setState is called before commit in a dehydrated component', async () => {
let suspend = false;
let resolve;
@ -1018,7 +1004,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(container.textContent).toBe('Hello');
});
// @gate experimental
it('blocks the update to hydrate first if context has changed', async () => {
let suspend = false;
let resolve;
@ -1103,7 +1088,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(span.className).toBe('hi');
});
// @gate experimental
it('shows the fallback if context has changed before hydration completes and is still suspended', async () => {
let suspend = false;
let resolve;
@ -1187,7 +1171,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(container.textContent).toBe('Hi');
});
// @gate experimental
it('replaces the fallback with client content if it is not rendered by the server', async () => {
let suspend = false;
const promise = new Promise(resolvePromise => {});
@ -1236,7 +1219,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(ref.current).toBe(span);
});
// @gate experimental
it('replaces the fallback within the suspended time if there is a nested suspense', async () => {
let suspend = false;
const promise = new Promise(resolvePromise => {});
@ -1296,7 +1278,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(ref.current).toBe(span);
});
// @gate experimental
it('replaces the fallback within the suspended time if there is a nested suspense in a nested suspense', async () => {
let suspend = false;
const promise = new Promise(resolvePromise => {});
@ -1358,7 +1339,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(ref.current).toBe(span);
});
// @gate experimental
it('shows inserted items in a SuspenseList before content is hydrated', async () => {
let suspend = false;
let resolve;
@ -1444,7 +1424,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(ref.current).toBe(spanB);
});
// @gate experimental
it('shows is able to hydrate boundaries even if others in a list are pending', async () => {
let suspend = false;
let resolve;
@ -1591,7 +1570,7 @@ describe('ReactDOMServerPartialHydration', () => {
await act(async () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<App />);
});
@ -1622,7 +1601,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(ref.current).toBe(b);
});
// @gate experimental
it('clears server boundaries when SuspenseList suspends last row hydrating', async () => {
let suspend = false;
let resolve;
@ -1679,7 +1657,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(container.textContent).toBe('AB');
});
// @gate experimental
it('can client render nested boundaries', async () => {
let suspend = false;
const promise = new Promise(() => {});
@ -1734,7 +1711,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(container.lastChild.data).toBe('unrelated comment');
});
// @gate experimental
it('can hydrate TWO suspense boundaries', async () => {
const ref1 = React.createRef();
const ref2 = React.createRef();
@ -1774,7 +1750,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(ref2.current).toBe(span2);
});
// @gate experimental
it('regenerates if it cannot hydrate before changes to props/context expire', async () => {
let suspend = false;
const promise = new Promise(resolvePromise => {});
@ -1856,7 +1831,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(newSpan.className).toBe('hi');
});
// @gate experimental
it('does not invoke an event on a hydrated node until it commits', async () => {
let suspend = false;
let resolve;
@ -2022,7 +1996,6 @@ describe('ReactDOMServerPartialHydration', () => {
document.body.removeChild(container);
});
// @gate experimental
it('invokes discrete events on nested suspense boundaries in a root (legacy system)', async () => {
let suspend = false;
let resolve;
@ -2190,7 +2163,6 @@ describe('ReactDOMServerPartialHydration', () => {
document.body.removeChild(container);
});
// @gate experimental
it('does not invoke the parent of dehydrated boundary event', async () => {
let suspend = false;
let resolve;
@ -2266,7 +2238,6 @@ describe('ReactDOMServerPartialHydration', () => {
document.body.removeChild(container);
});
// @gate experimental
it('does not invoke an event on a parent tree when a subtree is dehydrated', async () => {
let suspend = false;
let resolve;
@ -2345,7 +2316,6 @@ describe('ReactDOMServerPartialHydration', () => {
document.body.removeChild(parentContainer);
});
// @gate experimental
it('blocks only on the last continuous event (legacy system)', async () => {
let suspend1 = false;
let resolve1;
@ -2450,7 +2420,6 @@ describe('ReactDOMServerPartialHydration', () => {
document.body.removeChild(container);
});
// @gate experimental
it('finishes normal pri work before continuing to hydrate a retry', async () => {
let suspend = false;
let resolve;
@ -2532,7 +2501,6 @@ describe('ReactDOMServerPartialHydration', () => {
expect(ref.current).not.toBe(null);
});
// @gate experimental
it('regression test: does not overfire non-bubbling browser events', async () => {
let suspend = false;
let resolve;
@ -2623,7 +2591,6 @@ describe('ReactDOMServerPartialHydration', () => {
// follow up.
//
// @gate FIXME
// @gate experimental
it('hydrates a hidden subtree outside of a Suspense boundary', async () => {
const ref = React.createRef();

View File

@ -126,7 +126,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
IdleEventPriority = require('react-reconciler/constants').IdleEventPriority;
});
// @gate experimental
it('hydrates the target boundary synchronously during a click', async () => {
function Child({text}) {
Scheduler.unstable_yieldValue(text);
@ -189,7 +188,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
document.body.removeChild(container);
});
// @gate experimental
it('hydrates at higher pri if sync did not work first time', async () => {
let suspend = false;
let resolve;
@ -277,7 +275,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
document.body.removeChild(container);
});
// @gate experimental
it('hydrates at higher pri for secondary discrete events', async () => {
let suspend = false;
let resolve;
@ -628,7 +625,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
document.body.removeChild(container);
});
// @gate experimental
it('hydrates the hovered targets as higher priority for continuous events', async () => {
let suspend = false;
let resolve;
@ -731,7 +727,6 @@ describe('ReactDOMServerSelectiveHydration', () => {
document.body.removeChild(container);
});
// @gate experimental
it('hydrates the last target path first for continuous events', async () => {
let suspend = false;
let resolve;

View File

@ -93,7 +93,6 @@ describe('ReactDOMServerSuspense', () => {
: children;
}
// @gate experimental || www
it('should render the children when no promise is thrown', async () => {
const c = await serverRender(
<div>
@ -105,7 +104,6 @@ describe('ReactDOMServerSuspense', () => {
expect(getVisibleChildren(c)).toEqual(<div>Children</div>);
});
// @gate experimental || www
it('should render the fallback when a promise thrown', async () => {
const c = await serverRender(
<div>
@ -117,7 +115,6 @@ describe('ReactDOMServerSuspense', () => {
expect(getVisibleChildren(c)).toEqual(<div>Fallback</div>);
});
// @gate experimental || www
it('should work with nested suspense components', async () => {
const c = await serverRender(
<div>
@ -140,7 +137,6 @@ describe('ReactDOMServerSuspense', () => {
);
});
// @gate experimental
it('server renders a SuspenseList component and its children', async () => {
const example = (
<React.SuspenseList>

View File

@ -492,12 +492,11 @@ describe('ReactDOMServerHydration', () => {
expect(element.textContent).toBe('Hello world');
});
// @gate experimental
it('does not re-enter hydration after committing the first one', () => {
const finalHTML = ReactDOMServer.renderToString(<div />);
const container = document.createElement('div');
container.innerHTML = finalHTML;
const root = ReactDOM.unstable_createRoot(container, {hydrate: true});
const root = ReactDOM.createRoot(container, {hydrate: true});
root.render(<div />);
Scheduler.unstable_flushAll();
root.render(null);

View File

@ -29,7 +29,7 @@ describe('ReactTestUtils.act()', () => {
if (__EXPERIMENTAL__) {
let concurrentRoot = null;
const renderConcurrent = (el, dom) => {
concurrentRoot = ReactDOM.unstable_createRoot(dom);
concurrentRoot = ReactDOM.createRoot(dom);
concurrentRoot.render(el);
};
@ -96,20 +96,17 @@ describe('ReactTestUtils.act()', () => {
]);
});
// @gate experimental
it('does not warn in concurrent mode', () => {
const root = ReactDOM.unstable_createRoot(document.createElement('div'));
const root = ReactDOM.createRoot(document.createElement('div'));
root.render(<App />);
Scheduler.unstable_flushAll();
});
// @gate experimental
it('warns in concurrent mode if root is strict', () => {
expect(() => {
const root = ReactDOM.unstable_createRoot(
document.createElement('div'),
{unstable_strictMode: true},
);
const root = ReactDOM.createRoot(document.createElement('div'), {
unstable_strictMode: true,
});
root.render(<App />);
Scheduler.unstable_flushAll();
}).toErrorDev([
@ -665,7 +662,7 @@ function runActTests(label, render, unmount, rerender) {
expect(document.querySelector('[data-test-id=spinner]')).toBeNull();
// trigger a suspendy update with a delay
React.unstable_startTransition(() => {
React.startTransition(() => {
act(() => {
rerender(<App suspend={true} />);
});

View File

@ -29,10 +29,9 @@ it('does not warn when rendering in legacy mode', () => {
}).toErrorDev([]);
});
// @gate experimental
it('should warn when rendering in concurrent mode', () => {
expect(() => {
ReactDOM.unstable_createRoot(document.createElement('div')).render(<App />);
ReactDOM.createRoot(document.createElement('div')).render(<App />);
}).toErrorDev(
'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' +
'to guarantee consistent behaviour across tests and browsers.',
@ -40,6 +39,6 @@ it('should warn when rendering in concurrent mode', () => {
);
// does not warn twice
expect(() => {
ReactDOM.unstable_createRoot(document.createElement('div')).render(<App />);
ReactDOM.createRoot(document.createElement('div')).render(<App />);
}).toErrorDev([]);
});

View File

@ -1332,7 +1332,7 @@ describe('ReactUpdates', () => {
);
}
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
let hiddenDiv;
act(() => {
root.render(<Foo />);

View File

@ -22,7 +22,7 @@ beforeEach(() => {
Scheduler = require('scheduler');
Suspense = React.Suspense;
SuspenseList = React.unstable_SuspenseList;
SuspenseList = React.SuspenseList;
getCacheForType = React.unstable_getCacheForType;

View File

@ -78,7 +78,6 @@ setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority);
setGetCurrentUpdatePriority(getCurrentUpdatePriority);
setAttemptHydrationAtPriority(runWithPriority);
let didWarnAboutUnstableCreatePortal = false;
let didWarnAboutUnstableRenderSubtreeIntoContainer = false;
if (__DEV__) {
@ -155,25 +154,6 @@ function renderSubtreeIntoContainer(
);
}
function unstable_createPortal(
children: ReactNodeList,
container: Container,
key: ?string = null,
) {
if (__DEV__) {
if (!didWarnAboutUnstableCreatePortal) {
didWarnAboutUnstableCreatePortal = true;
console.warn(
'The ReactDOM.unstable_createPortal() alias has been deprecated, ' +
'and will be removed in React 18+. Update your code to use ' +
'ReactDOM.createPortal() instead. It has the exact same API, ' +
'but without the "unstable_" prefix.',
);
}
}
return createPortal(children, container, key);
}
const Internals = {
// Keep in sync with ReactTestUtils.js, and ReactTestUtilsAct.js.
// This is an array for better minification.
@ -206,10 +186,6 @@ export {
scheduleHydration as unstable_scheduleHydration,
// Disabled behind disableUnstableRenderSubtreeIntoContainer
renderSubtreeIntoContainer as unstable_renderSubtreeIntoContainer,
// Disabled behind disableUnstableCreatePortal
// Temporary alias since we already shipped React 16 RC with it.
// TODO: remove in React 18.
unstable_createPortal,
// enableCreateEventHandleAPI
createEventHandle as unstable_createEventHandle,
// TODO: Remove this once callers migrate to alternatives.

View File

@ -575,7 +575,6 @@ describe('DOMPluginEventSystem', () => {
expect(log).toEqual(['second', 'first']);
});
// @gate experimental
it('does not invoke an event on a parent tree when a subtree is dehydrated', async () => {
let suspend = false;
let resolve;
@ -1951,7 +1950,7 @@ describe('DOMPluginEventSystem', () => {
// Increase counter
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<Test counter={1} />);
});
} else {

View File

@ -495,9 +495,8 @@ describe('ChangeEventPlugin', () => {
});
describe('concurrent mode', () => {
// @gate experimental
it('text input', () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
let input;
class ControlledInput extends React.Component {
@ -538,9 +537,8 @@ describe('ChangeEventPlugin', () => {
expect(input.value).toBe('changed [!]');
});
// @gate experimental
it('checkbox input', () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
let input;
class ControlledInput extends React.Component {
@ -594,9 +592,8 @@ describe('ChangeEventPlugin', () => {
expect(input.checked).toBe(false);
});
// @gate experimental
it('textarea', () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
let textarea;
class ControlledTextarea extends React.Component {
@ -637,9 +634,8 @@ describe('ChangeEventPlugin', () => {
expect(textarea.value).toBe('changed [!]');
});
// @gate experimental
it('parent of input', () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
let input;
class ControlledInput extends React.Component {
@ -684,9 +680,8 @@ describe('ChangeEventPlugin', () => {
expect(input.value).toBe('changed [!]');
});
// @gate experimental
it('is sync for non-input events', async () => {
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
let input;
class ControlledInput extends React.Component {
@ -731,12 +726,11 @@ describe('ChangeEventPlugin', () => {
expect(input.value).toBe('');
});
// @gate experimental
it('mouse enter/leave should be user-blocking but not discrete', async () => {
const {unstable_concurrentAct: act} = TestUtils;
const {useState} = React;
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
const target = React.createRef(null);
function Foo() {

View File

@ -240,10 +240,9 @@ describe('SimpleEventPlugin', function() {
act = require('react-dom/test-utils').unstable_concurrentAct;
});
// @gate experimental
it('flushes pending interactive work before exiting event handler', async () => {
container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
document.body.appendChild(container);
let button;
@ -316,10 +315,9 @@ describe('SimpleEventPlugin', function() {
// NOTE: This test was written for the old behavior of discrete updates,
// where they would be async, but flushed early if another discrete update
// was dispatched.
// @gate experimental
it('end result of many interactive updates is deterministic', async () => {
container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
document.body.appendChild(container);
let button;

View File

@ -23,7 +23,7 @@ export {
Profiler,
StrictMode,
Suspense,
unstable_SuspenseList,
SuspenseList,
isAsyncMode,
isConcurrentMode,
isContextConsumer,
@ -37,5 +37,5 @@ export {
isProfiler,
isStrictMode,
isSuspense,
unstable_isSuspenseList,
isSuspenseList,
} from './src/ReactIs';

View File

@ -23,6 +23,7 @@ export {
Profiler,
StrictMode,
Suspense,
SuspenseList,
isAsyncMode,
isConcurrentMode,
isContextConsumer,
@ -36,4 +37,5 @@ export {
isProfiler,
isStrictMode,
isSuspense,
isSuspenseList,
} from './src/ReactIs';

View File

@ -72,7 +72,7 @@ export const Portal = REACT_PORTAL_TYPE;
export const Profiler = REACT_PROFILER_TYPE;
export const StrictMode = REACT_STRICT_MODE_TYPE;
export const Suspense = REACT_SUSPENSE_TYPE;
export const unstable_SuspenseList = REACT_SUSPENSE_LIST_TYPE;
export const SuspenseList = REACT_SUSPENSE_LIST_TYPE;
export {isValidElementType};
@ -143,6 +143,6 @@ export function isStrictMode(object: any) {
export function isSuspense(object: any) {
return typeOf(object) === REACT_SUSPENSE_TYPE;
}
export function unstable_isSuspenseList(object: any) {
export function isSuspenseList(object: any) {
return typeOf(object) === REACT_SUSPENSE_LIST_TYPE;
}

View File

@ -186,22 +186,13 @@ describe('ReactIs', () => {
expect(ReactIs.isSuspense(<div />)).toBe(false);
});
// @gate experimental
it('should identify suspense list', () => {
expect(ReactIs.isValidElementType(React.unstable_SuspenseList)).toBe(true);
expect(ReactIs.typeOf(<React.unstable_SuspenseList />)).toBe(
ReactIs.unstable_SuspenseList,
);
expect(
ReactIs.unstable_isSuspenseList(<React.unstable_SuspenseList />),
).toBe(true);
expect(
ReactIs.unstable_isSuspenseList({type: ReactIs.unstable_SuspenseList}),
).toBe(false);
expect(ReactIs.unstable_isSuspenseList('React.unstable_SuspenseList')).toBe(
false,
);
expect(ReactIs.unstable_isSuspenseList(<div />)).toBe(false);
expect(ReactIs.isValidElementType(React.SuspenseList)).toBe(true);
expect(ReactIs.typeOf(<React.SuspenseList />)).toBe(ReactIs.SuspenseList);
expect(ReactIs.isSuspenseList(<React.SuspenseList />)).toBe(true);
expect(ReactIs.isSuspenseList({type: ReactIs.SuspenseList})).toBe(false);
expect(ReactIs.isSuspenseList('React.SuspenseList')).toBe(false);
expect(ReactIs.isSuspenseList(<div />)).toBe(false);
});
it('should identify profile root', () => {

View File

@ -22,7 +22,7 @@ describe('ReactCache', () => {
Suspense = React.Suspense;
getCacheForType = React.unstable_getCacheForType;
useCacheRefresh = React.unstable_useCacheRefresh;
startTransition = React.unstable_startTransition;
startTransition = React.startTransition;
useState = React.useState;
caches = [];

View File

@ -19,7 +19,7 @@ describe('ReactLazyContextPropagation', () => {
useState = React.useState;
useContext = React.useContext;
Suspense = React.Suspense;
SuspenseList = React.unstable_SuspenseList;
SuspenseList = React.SuspenseList;
getCacheForType = React.unstable_getCacheForType;
@ -649,8 +649,6 @@ describe('ReactLazyContextPropagation', () => {
expect(root).toMatchRenderedOutput('BBB');
});
// @gate enableCache
// @gate experimental
test('contexts are propagated through SuspenseList', async () => {
// This kinda tests an implementation detail. SuspenseList has an early
// bailout that doesn't use `bailoutOnAlreadyFinishedWork`. It probably

View File

@ -45,7 +45,6 @@ describe('ReactSuspenseList', () => {
return Component;
}
// @gate experimental || !enableSyncDefaultUpdates
it('appends rendering tasks to the end of the priority queue', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -65,7 +64,7 @@ describe('ReactSuspenseList', () => {
expect(Scheduler).toFlushAndYield([]);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<App show={true} />);
});
} else {

View File

@ -25,7 +25,7 @@ describe('ReactExpiration', () => {
React = require('react');
ReactNoop = require('react-noop-renderer');
Scheduler = require('scheduler');
startTransition = React.unstable_startTransition;
startTransition = React.startTransition;
useState = React.useState;
useEffect = React.useEffect;
@ -115,10 +115,10 @@ describe('ReactExpiration', () => {
// Flush the sync task.
ReactNoop.flushSync();
}
// @gate experimental || !enableSyncDefaultUpdates
it('increases priority of updates as time progresses', () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<span prop="done" />);
});
} else {
@ -142,7 +142,6 @@ describe('ReactExpiration', () => {
expect(ReactNoop.getChildren()).toEqual([span('done')]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('two updates of like priority in the same event always flush within the same batch', () => {
class TextClass extends React.Component {
componentDidMount() {
@ -166,7 +165,7 @@ describe('ReactExpiration', () => {
// First, show what happens for updates in two separate events.
// Schedule an update.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<TextClass text="A" />);
});
} else {
@ -201,7 +200,6 @@ describe('ReactExpiration', () => {
expect(Scheduler).toFlushAndYield(['B [render]', 'B [commit]']);
});
// @gate experimental || !enableSyncDefaultUpdates
it(
'two updates of like priority in the same event always flush within the ' +
"same batch, even if there's a sync update in between",
@ -228,7 +226,7 @@ describe('ReactExpiration', () => {
// First, show what happens for updates in two separate events.
// Schedule an update.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<TextClass text="A" />);
});
} else {
@ -269,7 +267,6 @@ describe('ReactExpiration', () => {
},
);
// @gate experimental || !enableSyncDefaultUpdates
it('cannot update at the same expiration time that is already rendering', () => {
const store = {text: 'initial'};
const subscribers = [];
@ -307,7 +304,7 @@ describe('ReactExpiration', () => {
// Initial mount
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App />);
});
} else {
@ -326,7 +323,7 @@ describe('ReactExpiration', () => {
// Partial update
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
subscribers.forEach(s => s.setState({text: '1'}));
});
} else {
@ -347,7 +344,6 @@ describe('ReactExpiration', () => {
]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('stops yielding if CPU-bound update takes too long to finish', () => {
const root = ReactNoop.createRoot();
function App() {
@ -363,7 +359,7 @@ describe('ReactExpiration', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<App />);
});
} else {
@ -381,7 +377,6 @@ describe('ReactExpiration', () => {
expect(root).toMatchRenderedOutput('ABCDE');
});
// @gate experimental || !enableSyncDefaultUpdates
it('root expiration is measured from the time of the first update', () => {
Scheduler.unstable_advanceTime(10000);
@ -398,7 +393,7 @@ describe('ReactExpiration', () => {
);
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<App />);
});
} else {
@ -416,7 +411,6 @@ describe('ReactExpiration', () => {
expect(root).toMatchRenderedOutput('ABCDE');
});
// @gate experimental || !enableSyncDefaultUpdates
it('should measure expiration times relative to module initialization', () => {
// Tests an implementation detail where expiration times are computed using
// bitwise operations.
@ -433,7 +427,7 @@ describe('ReactExpiration', () => {
ReactNoop = require('react-noop-renderer');
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render('Hi');
});
} else {
@ -453,7 +447,6 @@ describe('ReactExpiration', () => {
expect(ReactNoop).toMatchRenderedOutput('Hi');
});
// @gate experimental || !enableSyncDefaultUpdates
it('should measure callback timeout relative to current time, not start-up time', () => {
// Corresponds to a bugfix: https://github.com/facebook/react/pull/15479
// The bug wasn't caught by other tests because we use virtual times that
@ -463,7 +456,7 @@ describe('ReactExpiration', () => {
Scheduler.unstable_advanceTime(10000);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render('Hi');
});
} else {
@ -481,7 +474,6 @@ describe('ReactExpiration', () => {
expect(ReactNoop).toMatchRenderedOutput('Hi');
});
// @gate experimental || !enableSyncDefaultUpdates
it('prevents starvation by sync updates by disabling time slicing if too much time has elapsed', async () => {
let updateSyncPri;
let updateNormalPri;
@ -513,7 +505,7 @@ describe('ReactExpiration', () => {
// First demonstrate what happens when there's no starvation
await ReactNoop.act(async () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
updateNormalPri();
});
} else {
@ -537,7 +529,7 @@ describe('ReactExpiration', () => {
// Do the same thing, but starve the first update
await ReactNoop.act(async () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
updateNormalPri();
});
} else {
@ -628,7 +620,6 @@ describe('ReactExpiration', () => {
expect(root).toMatchRenderedOutput('Sync pri: 2, Idle pri: 2');
});
// @gate experimental
it('when multiple lanes expire, we can finish the in-progress one without including the others', async () => {
let setA;
let setB;
@ -677,7 +668,6 @@ describe('ReactExpiration', () => {
});
});
// @gate experimental || !enableSyncDefaultUpdates
it('updates do not expire while they are IO-bound', async () => {
const {Suspense} = React;
@ -701,7 +691,7 @@ describe('ReactExpiration', () => {
await ReactNoop.act(async () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<App step={1} />);
});
} else {
@ -734,7 +724,6 @@ describe('ReactExpiration', () => {
});
});
// @gate experimental
it('flushSync should not affect expired work', async () => {
let setA;
let setB;
@ -778,7 +767,6 @@ describe('ReactExpiration', () => {
});
});
// @gate experimental
it('passive effects of expired update flush after paint', async () => {
function App({step}) {
useEffect(() => {

View File

@ -14,7 +14,7 @@ describe('ReactFlushSync', () => {
Scheduler = require('scheduler');
useState = React.useState;
useEffect = React.useEffect;
startTransition = React.unstable_startTransition;
startTransition = React.startTransition;
});
function Text({text}) {
@ -22,7 +22,6 @@ describe('ReactFlushSync', () => {
return text;
}
// @gate experimental || !enableSyncDefaultUpdates
test('changes priority of updates in useEffect', async () => {
function App() {
const [syncState, setSyncState] = useState(0);
@ -39,7 +38,7 @@ describe('ReactFlushSync', () => {
const root = ReactNoop.createRoot();
await ReactNoop.act(async () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<App />);
});
} else {
@ -64,7 +63,6 @@ describe('ReactFlushSync', () => {
expect(root).toMatchRenderedOutput('1, 1');
});
// @gate experimental
test('nested with startTransition', async () => {
let setSyncState;
let setState;

View File

@ -52,8 +52,8 @@ describe('ReactHooksWithNoopRenderer', () => {
useImperativeHandle = React.useImperativeHandle;
forwardRef = React.forwardRef;
memo = React.memo;
useTransition = React.unstable_useTransition;
useDeferredValue = React.unstable_useDeferredValue;
useTransition = React.useTransition;
useDeferredValue = React.useDeferredValue;
Suspense = React.Suspense;
act = ReactNoop.act;
ContinuousEventPriority = require('react-reconciler/constants')
@ -149,7 +149,6 @@ describe('ReactHooksWithNoopRenderer', () => {
return Promise.resolve().then(() => {});
}
// @gate experimental || !enableSyncDefaultUpdates
it('resumes after an interruption', () => {
function Counter(props, ref) {
const [count, updateCount] = useState(0);
@ -166,7 +165,7 @@ describe('ReactHooksWithNoopRenderer', () => {
// Schedule some updates
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
// TODO: Batched updates need to be inside startTransition?
ReactNoop.batchedUpdates(() => {
counter.current.updateCount(1);
@ -691,7 +690,6 @@ describe('ReactHooksWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span(22)]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('discards render phase updates if something suspends', async () => {
const thenable = {then() {}};
function Foo({signal}) {
@ -728,7 +726,7 @@ describe('ReactHooksWithNoopRenderer', () => {
expect(root).toMatchRenderedOutput(<span prop={0} />);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<Foo signal={false} />);
});
} else {
@ -739,7 +737,7 @@ describe('ReactHooksWithNoopRenderer', () => {
// Rendering again should suspend again.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<Foo signal={false} />);
});
} else {
@ -748,7 +746,6 @@ describe('ReactHooksWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYield(['Suspend!']);
});
// @gate experimental || !enableSyncDefaultUpdates
it('discards render phase updates if something suspends, but not other updates in the same component', async () => {
const thenable = {then() {}};
function Foo({signal}) {
@ -792,7 +789,7 @@ describe('ReactHooksWithNoopRenderer', () => {
await ReactNoop.act(async () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<Foo signal={false} />);
setLabel('B');
});
@ -806,7 +803,7 @@ describe('ReactHooksWithNoopRenderer', () => {
// Rendering again should suspend again.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<Foo signal={false} />);
});
} else {
@ -817,7 +814,7 @@ describe('ReactHooksWithNoopRenderer', () => {
// Flip the signal back to "cancel" the update. However, the update to
// label should still proceed. It shouldn't have been dropped.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<Foo signal={true} />);
});
} else {
@ -864,13 +861,12 @@ describe('ReactHooksWithNoopRenderer', () => {
});
// TODO: This should probably warn
// @gate experimental
it('calling startTransition inside render phase', async () => {
function App() {
const [counter, setCounter] = useState(0);
if (counter === 0) {
React.unstable_startTransition(() => {
React.startTransition(() => {
setCounter(c => c + 1);
});
}
@ -1315,7 +1311,6 @@ describe('ReactHooksWithNoopRenderer', () => {
});
});
// @gate experimental || !enableSyncDefaultUpdates
it('does not warn about state updates for unmounted components with pending passive unmounts for alternates', () => {
let setParentState = null;
const setChildStates = [];
@ -1383,7 +1378,7 @@ describe('ReactHooksWithNoopRenderer', () => {
// Schedule another update for children, and partially process it.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
setChildStates.forEach(setChildState => setChildState(2));
});
} else {
@ -1685,7 +1680,6 @@ describe('ReactHooksWithNoopRenderer', () => {
});
});
// @gate experimental || !enableSyncDefaultUpdates
it('updates have async priority even if effects are flushed early', () => {
function Counter(props) {
const [count, updateCount] = useState('(empty)');
@ -1707,7 +1701,7 @@ describe('ReactHooksWithNoopRenderer', () => {
// Rendering again should flush the previous commit's effects
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Counter count={1} />, () =>
Scheduler.unstable_yieldValue('Sync effect'),
);
@ -3127,8 +3121,8 @@ describe('ReactHooksWithNoopRenderer', () => {
expect(totalRefUpdates).toBe(2); // Should not increase since last time
});
});
describe('useTransition', () => {
// @gate experimental
it('delays showing loading state until after timeout', async () => {
let transition;
function App() {
@ -3190,7 +3184,6 @@ describe('ReactHooksWithNoopRenderer', () => {
});
describe('useDeferredValue', () => {
// @gate experimental
it('defers text value', async () => {
function TextBox({text}) {
return <AsyncText text={text} />;
@ -3694,9 +3687,8 @@ describe('ReactHooksWithNoopRenderer', () => {
]);
});
// @gate experimental
it('regression: SuspenseList causes unmounts to be dropped on deletion', async () => {
const SuspenseList = React.unstable_SuspenseList;
const SuspenseList = React.SuspenseList;
function Row({label}) {
useEffect(() => {

View File

@ -50,7 +50,6 @@ describe('ReactIncremental', () => {
expect(Scheduler).toFlushWithoutYielding();
});
// @gate experimental || !enableSyncDefaultUpdates
it('should render a simple component, in steps if needed', () => {
function Bar() {
Scheduler.unstable_yieldValue('Bar');
@ -67,7 +66,7 @@ describe('ReactIncremental', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo />, () =>
Scheduler.unstable_yieldValue('callback'),
);
@ -143,7 +142,6 @@ describe('ReactIncremental', () => {
]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('can cancel partially rendered work and restart', () => {
function Bar(props) {
Scheduler.unstable_yieldValue('Bar');
@ -165,7 +163,7 @@ describe('ReactIncremental', () => {
expect(Scheduler).toFlushAndYield(['Foo', 'Bar', 'Bar']);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo text="bar" />);
});
} else {
@ -178,7 +176,7 @@ describe('ReactIncremental', () => {
ReactNoop.flushSync(() => ReactNoop.render(null));
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo text="baz" />);
});
} else {
@ -192,7 +190,6 @@ describe('ReactIncremental', () => {
expect(Scheduler).toFlushAndYield(['Bar']);
});
// @gate experimental || !enableSyncDefaultUpdates
it('should call callbacks even if updates are aborted', () => {
let inst;
@ -219,7 +216,7 @@ describe('ReactIncremental', () => {
expect(Scheduler).toFlushWithoutYielding();
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
inst.setState(
() => {
Scheduler.unstable_yieldValue('setState1');
@ -244,7 +241,7 @@ describe('ReactIncremental', () => {
// This will abort the previous work and restart
ReactNoop.flushSync(() => ReactNoop.render(<Foo />));
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
inst.setState(
() => {
Scheduler.unstable_yieldValue('setState2');
@ -1764,7 +1761,6 @@ describe('ReactIncremental', () => {
expect(instance.state.n).toEqual(3);
});
// @gate experimental || !enableSyncDefaultUpdates
it('merges and masks context', () => {
class Intl extends React.Component {
static childContextTypes = {
@ -1883,7 +1879,7 @@ describe('ReactIncremental', () => {
'ShowBoth {"locale":"de"}',
]);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<Intl locale="sv">
<ShowLocale />
@ -2033,7 +2029,7 @@ describe('ReactIncremental', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<Intl locale="fr">
<ShowLocale />
@ -2739,7 +2735,6 @@ describe('ReactIncremental', () => {
expect(Scheduler).toFlushAndYield(['count:1, name:not brian']);
});
// @gate experimental || !enableSyncDefaultUpdates
it('does not interrupt for update at same priority', () => {
function Parent(props) {
Scheduler.unstable_yieldValue('Parent: ' + props.step);
@ -2752,7 +2747,7 @@ describe('ReactIncremental', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Parent step={1} />);
});
} else {
@ -2766,7 +2761,6 @@ describe('ReactIncremental', () => {
expect(Scheduler).toFlushAndYield(['Child: 1', 'Parent: 2', 'Child: 2']);
});
// @gate experimental || !enableSyncDefaultUpdates
it('does not interrupt for update at lower priority', () => {
function Parent(props) {
Scheduler.unstable_yieldValue('Parent: ' + props.step);
@ -2779,7 +2773,7 @@ describe('ReactIncremental', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Parent step={1} />);
});
} else {
@ -2794,7 +2788,6 @@ describe('ReactIncremental', () => {
expect(Scheduler).toFlushAndYield(['Child: 1', 'Parent: 2', 'Child: 2']);
});
// @gate experimental || !enableSyncDefaultUpdates
it('does interrupt for update at higher priority', () => {
function Parent(props) {
Scheduler.unstable_yieldValue('Parent: ' + props.step);
@ -2807,7 +2800,7 @@ describe('ReactIncremental', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Parent step={1} />);
});
} else {

View File

@ -58,7 +58,6 @@ describe('ReactIncrementalErrorHandling', () => {
);
}
// @gate experimental || !enableSyncDefaultUpdates
it('recovers from errors asynchronously', () => {
class ErrorBoundary extends React.Component {
state = {error: null};
@ -92,7 +91,7 @@ describe('ReactIncrementalErrorHandling', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<ErrorBoundary>
<Indirection>
@ -171,7 +170,6 @@ describe('ReactIncrementalErrorHandling', () => {
expect(ReactNoop.getChildren()).toEqual([span('Caught an error: oops!')]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('recovers from errors asynchronously (legacy, no getDerivedStateFromError)', () => {
class ErrorBoundary extends React.Component {
state = {error: null};
@ -205,7 +203,7 @@ describe('ReactIncrementalErrorHandling', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<ErrorBoundary>
<Indirection>
@ -270,7 +268,6 @@ describe('ReactIncrementalErrorHandling', () => {
expect(ReactNoop.getChildren()).toEqual([span('Caught an error: oops!')]);
});
// @gate experimental
it("retries at a lower priority if there's additional pending work", async () => {
function App(props) {
if (props.isBroken) {
@ -285,12 +282,12 @@ describe('ReactIncrementalErrorHandling', () => {
Scheduler.unstable_yieldValue('commit');
}
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App isBroken={true} />, onCommit);
});
expect(Scheduler).toFlushAndYieldThrough(['error']);
React.unstable_startTransition(() => {
React.startTransition(() => {
// This update is in a separate batch
ReactNoop.render(<App isBroken={false} />, onCommit);
});
@ -333,14 +330,14 @@ describe('ReactIncrementalErrorHandling', () => {
Scheduler.unstable_yieldValue('commit');
}
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App isBroken={true} />, onCommit);
});
expect(Scheduler).toFlushAndYieldThrough(['error']);
expect(ReactNoop).toMatchRenderedOutput(null);
React.unstable_startTransition(() => {
React.startTransition(() => {
// This update is in a separate batch
ReactNoop.render(<App isBroken={false} />, onCommit);
});
@ -378,7 +375,6 @@ describe('ReactIncrementalErrorHandling', () => {
);
});
// @gate experimental || !enableSyncDefaultUpdates
it('retries one more time before handling error', () => {
function BadRender({unused}) {
Scheduler.unstable_yieldValue('BadRender');
@ -401,7 +397,7 @@ describe('ReactIncrementalErrorHandling', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Parent />, () =>
Scheduler.unstable_yieldValue('commit'),
);
@ -429,7 +425,6 @@ describe('ReactIncrementalErrorHandling', () => {
expect(ReactNoop.getChildren()).toEqual([]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('retries one more time if an error occurs during a render that expires midway through the tree', async () => {
function Oops({unused}) {
Scheduler.unstable_yieldValue('Oops');
@ -454,7 +449,7 @@ describe('ReactIncrementalErrorHandling', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App />);
});
} else {
@ -566,7 +561,6 @@ describe('ReactIncrementalErrorHandling', () => {
expect(ReactNoop.getChildren()).toEqual([span('Caught an error: Hello.')]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('catches render error in a boundary during partial deferred mounting', () => {
class ErrorBoundary extends React.Component {
state = {error: null};
@ -592,7 +586,7 @@ describe('ReactIncrementalErrorHandling', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<ErrorBoundary>
<BrokenRender />
@ -757,7 +751,6 @@ describe('ReactIncrementalErrorHandling', () => {
expect(ReactNoop.getChildren()).toEqual([]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('propagates an error from a noop error boundary during partial deferred mounting', () => {
class RethrowErrorBoundary extends React.Component {
componentDidCatch(error) {
@ -776,7 +769,7 @@ describe('ReactIncrementalErrorHandling', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<RethrowErrorBoundary>
<BrokenRender />
@ -1842,7 +1835,6 @@ describe('ReactIncrementalErrorHandling', () => {
});
}
// @gate experimental
it('uncaught errors should be discarded if the render is aborted', async () => {
const root = ReactNoop.createRoot();
@ -1853,7 +1845,7 @@ describe('ReactIncrementalErrorHandling', () => {
await ReactNoop.act(async () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<Oops />);
});
} else {
@ -1866,7 +1858,7 @@ describe('ReactIncrementalErrorHandling', () => {
// Interleaved update. When the root completes, instead of throwing the
// error, it should try rendering again. This update will cause it to
// recover gracefully.
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render('Everything is fine.');
});
});
@ -1875,7 +1867,6 @@ describe('ReactIncrementalErrorHandling', () => {
expect(root).toMatchRenderedOutput('Everything is fine.');
});
// @gate experimental
it('uncaught errors are discarded if the render is aborted, case 2', async () => {
const {useState} = React;
const root = ReactNoop.createRoot();
@ -1902,7 +1893,7 @@ describe('ReactIncrementalErrorHandling', () => {
await ReactNoop.act(async () => {
// Schedule a default pri and a low pri update on the root.
root.render(<Oops />);
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<AllGood />);
});

View File

@ -34,7 +34,6 @@ describe('ReactIncrementalReflection', () => {
return {type: 'span', children: [], prop, hidden: false};
}
// @gate experimental || !enableSyncDefaultUpdates
it('handles isMounted even when the initial render is deferred', () => {
const instances = [];
@ -65,7 +64,7 @@ describe('ReactIncrementalReflection', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo />);
});
} else {
@ -83,7 +82,6 @@ describe('ReactIncrementalReflection', () => {
expect(instances[0]._isMounted()).toBe(true);
});
// @gate experimental || !enableSyncDefaultUpdates
it('handles isMounted when an unmount is deferred', () => {
const instances = [];
@ -120,7 +118,7 @@ describe('ReactIncrementalReflection', () => {
expect(instances[0]._isMounted()).toBe(true);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo mount={false} />);
});
} else {
@ -138,7 +136,6 @@ describe('ReactIncrementalReflection', () => {
expect(instances[0]._isMounted()).toBe(false);
});
// @gate experimental || !enableSyncDefaultUpdates
it('finds no node before insertion and correct node before deletion', () => {
let classInstance = null;
@ -210,7 +207,7 @@ describe('ReactIncrementalReflection', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo step={0} />);
});
} else {
@ -250,7 +247,7 @@ describe('ReactIncrementalReflection', () => {
// The next step will render a new host node but won't get committed yet.
// We expect this to mutate the original Fiber.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo step={2} />);
});
} else {
@ -277,7 +274,7 @@ describe('ReactIncrementalReflection', () => {
// Render to null but don't commit it yet.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo step={3} />);
});
} else {

View File

@ -85,7 +85,6 @@ describe('ReactIncrementalScheduling', () => {
expect(ReactNoop).toMatchRenderedOutput(<span prop={5} />);
});
// @gate experimental || !enableSyncDefaultUpdates
it('works on deferred roots in the order they were scheduled', () => {
const {useEffect} = React;
function Text({text}) {
@ -109,7 +108,7 @@ describe('ReactIncrementalScheduling', () => {
// Schedule deferred work in the reverse order
ReactNoop.act(() => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.renderToRootWithID(<Text text="c:2" />, 'c');
ReactNoop.renderToRootWithID(<Text text="b:2" />, 'b');
});
@ -126,7 +125,7 @@ describe('ReactIncrementalScheduling', () => {
// Schedule last bit of work, it will get processed the last
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.renderToRootWithID(<Text text="a:2" />, 'a');
});
} else {
@ -146,7 +145,6 @@ describe('ReactIncrementalScheduling', () => {
});
});
// @gate experimental || !enableSyncDefaultUpdates
it('schedules sync updates when inside componentDidMount/Update', () => {
let instance;
@ -186,7 +184,7 @@ describe('ReactIncrementalScheduling', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo />);
});
} else {
@ -206,7 +204,7 @@ describe('ReactIncrementalScheduling', () => {
]);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
instance.setState({tick: 2});
});
} else {
@ -224,7 +222,6 @@ describe('ReactIncrementalScheduling', () => {
]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('can opt-in to async scheduling inside componentDidMount/Update', () => {
let instance;
class Foo extends React.Component {
@ -284,7 +281,7 @@ describe('ReactIncrementalScheduling', () => {
// Increment the tick to 2. This will trigger an update inside cDU. Flush
// the first update without flushing the second one.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
instance.setState({tick: 2});
});
@ -315,7 +312,6 @@ describe('ReactIncrementalScheduling', () => {
}
});
// @gate experimental || !enableSyncDefaultUpdates
it('performs Task work even after time runs out', () => {
class Foo extends React.Component {
state = {step: 1};
@ -334,7 +330,7 @@ describe('ReactIncrementalScheduling', () => {
}
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo />);
});
} else {

View File

@ -384,7 +384,6 @@ describe('ReactIncrementalSideEffects', () => {
expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('does not update child nodes if a flush is aborted', () => {
function Bar(props) {
Scheduler.unstable_yieldValue('Bar');
@ -411,7 +410,7 @@ describe('ReactIncrementalSideEffects', () => {
]);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo text="World" />);
});
} else {
@ -640,14 +639,13 @@ describe('ReactIncrementalSideEffects', () => {
);
});
// @gate experimental || !enableSyncDefaultUpdates
it('can update a completed tree before it has a chance to commit', () => {
function Foo(props) {
Scheduler.unstable_yieldValue('Foo');
return <span prop={props.step} />;
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo step={1} />);
});
} else {
@ -662,7 +660,7 @@ describe('ReactIncrementalSideEffects', () => {
expect(ReactNoop.getChildrenAsJSX()).toEqual(<span prop={1} />);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo step={2} />);
});
} else {
@ -675,7 +673,7 @@ describe('ReactIncrementalSideEffects', () => {
// new props
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo step={3} />);
});
} else {

View File

@ -131,7 +131,6 @@ describe('ReactIncrementalUpdates', () => {
expect(instance.state).toEqual({c: 'c', d: 'd'});
});
// @gate experimental || !enableSyncDefaultUpdates
it('can abort an update, schedule additional updates, and resume', () => {
let instance;
class Foo extends React.Component {
@ -162,7 +161,7 @@ describe('ReactIncrementalUpdates', () => {
// Schedule some async updates
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
instance.setState(createUpdate('a'));
instance.setState(createUpdate('b'));
instance.setState(createUpdate('c'));
@ -184,7 +183,7 @@ describe('ReactIncrementalUpdates', () => {
instance.setState(createUpdate('e'));
instance.setState(createUpdate('f'));
});
React.unstable_startTransition(() => {
React.startTransition(() => {
instance.setState(createUpdate('g'));
});
@ -229,7 +228,6 @@ describe('ReactIncrementalUpdates', () => {
}
});
// @gate experimental || !enableSyncDefaultUpdates
it('can abort an update, schedule a replaceState, and resume', () => {
let instance;
class Foo extends React.Component {
@ -260,7 +258,7 @@ describe('ReactIncrementalUpdates', () => {
// Schedule some async updates
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
instance.setState(createUpdate('a'));
instance.setState(createUpdate('b'));
instance.setState(createUpdate('c'));
@ -285,7 +283,7 @@ describe('ReactIncrementalUpdates', () => {
// reaching into the updater.
instance.updater.enqueueReplaceState(instance, createUpdate('f'));
});
React.unstable_startTransition(() => {
React.startTransition(() => {
instance.setState(createUpdate('g'));
});
@ -543,7 +541,6 @@ describe('ReactIncrementalUpdates', () => {
expect(ReactNoop.getChildren()).toEqual([span('derived state')]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('regression: does not expire soon due to layout effects in the last batch', () => {
const {useState, useLayoutEffect} = React;
@ -561,7 +558,7 @@ describe('ReactIncrementalUpdates', () => {
ReactNoop.act(() => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App />);
});
} else {
@ -577,7 +574,7 @@ describe('ReactIncrementalUpdates', () => {
Scheduler.unstable_advanceTime(10000);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
setCount(2);
});
} else {
@ -588,7 +585,6 @@ describe('ReactIncrementalUpdates', () => {
});
});
// @gate experimental || !enableSyncDefaultUpdates
it('regression: does not expire soon due to previous flushSync', () => {
function Text({text}) {
Scheduler.unstable_yieldValue(text);
@ -603,7 +599,7 @@ describe('ReactIncrementalUpdates', () => {
Scheduler.unstable_advanceTime(10000);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Text text="B" />);
});
} else {
@ -613,7 +609,6 @@ describe('ReactIncrementalUpdates', () => {
expect(Scheduler).toHaveYielded([]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('regression: does not expire soon due to previous expired work', () => {
function Text({text}) {
Scheduler.unstable_yieldValue(text);
@ -621,7 +616,7 @@ describe('ReactIncrementalUpdates', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Text text="A" />);
});
} else {
@ -634,7 +629,7 @@ describe('ReactIncrementalUpdates', () => {
Scheduler.unstable_advanceTime(10000);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Text text="B" />);
});
} else {
@ -644,7 +639,6 @@ describe('ReactIncrementalUpdates', () => {
expect(Scheduler).toHaveYielded([]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('when rebasing, does not exclude updates that were already committed, regardless of priority', async () => {
const {useState, useLayoutEffect} = React;
@ -678,7 +672,7 @@ describe('ReactIncrementalUpdates', () => {
await ReactNoop.act(async () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
pushToLog('A');
});
} else {
@ -707,7 +701,6 @@ describe('ReactIncrementalUpdates', () => {
expect(root).toMatchRenderedOutput('ABCD');
});
// @gate experimental || !enableSyncDefaultUpdates
it('when rebasing, does not exclude updates that were already committed, regardless of priority (classes)', async () => {
let pushToLog;
class App extends React.Component {
@ -740,7 +733,7 @@ describe('ReactIncrementalUpdates', () => {
await ReactNoop.act(async () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
pushToLog('A');
});
} else {

View File

@ -12,7 +12,7 @@ describe('ReactInterleavedUpdates', () => {
React = require('react');
ReactNoop = require('react-noop-renderer');
Scheduler = require('scheduler');
startTransition = React.unstable_startTransition;
startTransition = React.startTransition;
useState = React.useState;
useEffect = React.useEffect;
});
@ -22,7 +22,6 @@ describe('ReactInterleavedUpdates', () => {
return text;
}
// @gate experimental || !enableSyncDefaultUpdates
test('update during an interleaved event is not processed during the current render', async () => {
const updaters = [];
@ -57,7 +56,7 @@ describe('ReactInterleavedUpdates', () => {
await ReactNoop.act(async () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
updateChildren(1);
});
} else {
@ -69,7 +68,7 @@ describe('ReactInterleavedUpdates', () => {
// In an interleaved event, schedule an update on each of the children.
// Including the two that haven't rendered yet.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
updateChildren(2);
});
} else {
@ -85,7 +84,6 @@ describe('ReactInterleavedUpdates', () => {
expect(root).toMatchRenderedOutput('222');
});
// @gate experimental
// @gate !enableSyncDefaultUpdates
test('low priority update during an interleaved event is not processed during the current render', async () => {
// Same as previous test, but the interleaved update is lower priority than

View File

@ -1475,7 +1475,6 @@ describe('ReactLazy', () => {
});
// @gate enableLazyElements
// @gate experimental || !enableSyncDefaultUpdates
it('mount and reorder lazy elements', async () => {
class Child extends React.Component {
componentDidMount() {
@ -1536,7 +1535,7 @@ describe('ReactLazy', () => {
// Swap the position of A and B
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.update(<Parent swap={true} />);
});
} else {

View File

@ -828,7 +828,6 @@ describe('ReactNewContext', () => {
);
});
// @gate experimental || !enableSyncDefaultUpdates
it('warns if multiple renderers concurrently render the same context', () => {
spyOnDev(console, 'error');
const Context = React.createContext(0);
@ -848,7 +847,7 @@ describe('ReactNewContext', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App value={1} />);
});
} else {

View File

@ -28,7 +28,7 @@ describe('ReactSchedulerIntegration', () => {
NormalPriority = Scheduler.unstable_NormalPriority;
IdlePriority = Scheduler.unstable_IdlePriority;
runWithPriority = Scheduler.unstable_runWithPriority;
startTransition = React.unstable_startTransition;
startTransition = React.startTransition;
});
// Note: This is based on a similar component we use in www. We can delete
@ -88,7 +88,6 @@ describe('ReactSchedulerIntegration', () => {
]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('requests a paint after committing', () => {
const scheduleCallback = Scheduler.unstable_scheduleCallback;
@ -102,7 +101,7 @@ describe('ReactSchedulerIntegration', () => {
// Schedule a React render. React will request a paint after committing it.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render('Update');
});
} else {
@ -203,7 +202,7 @@ describe(
React = require('react');
ReactNoop = require('react-noop-renderer');
Scheduler = require('scheduler');
startTransition = React.unstable_startTransition;
startTransition = React.startTransition;
});
afterEach(() => {
@ -252,7 +251,6 @@ describe(
});
});
// @gate experimental
it('mock Scheduler module to check if `shouldYield` is called', async () => {
// This test reproduces a bug where React's Scheduler task timed out but
// the `shouldYield` method returned true. Usually we try not to mock

View File

@ -96,7 +96,6 @@ describe('ReactSuspense', () => {
}
}
// @gate experimental || !enableSyncDefaultUpdates
it('suspends rendering and continues later', () => {
function Bar(props) {
Scheduler.unstable_yieldValue('Bar');
@ -128,7 +127,7 @@ describe('ReactSuspense', () => {
// Navigate the shell to now render the child content.
// This should suspend.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.update(<Foo renderBar={true} />);
});
} else {
@ -201,7 +200,6 @@ describe('ReactSuspense', () => {
expect(root).toMatchRenderedOutput('AB');
});
// @gate experimental || !enableSyncDefaultUpdates
it('interrupts current render if promise resolves before current render phase', () => {
let didResolve = false;
const listeners = [];
@ -244,7 +242,7 @@ describe('ReactSuspense', () => {
// The update will suspend.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.update(
<>
<Suspense fallback={<Text text="Loading..." />}>
@ -289,7 +287,6 @@ describe('ReactSuspense', () => {
expect(root).toMatchRenderedOutput('AsyncAfter SuspenseSibling');
});
// @gate experimental
// @gate !enableSyncDefaultUpdates
it(
'interrupts current render when something suspends with a ' +
@ -331,7 +328,7 @@ describe('ReactSuspense', () => {
// Schedule another update. This will have lower priority because it's
// a transition.
React.unstable_startTransition(() => {
React.startTransition(() => {
root.update(<App shouldSuspend={false} step={2} />);
});

View File

@ -14,7 +14,7 @@ describe('ReactSuspenseList', () => {
Scheduler = require('scheduler');
Profiler = React.Profiler;
Suspense = React.Suspense;
SuspenseList = React.unstable_SuspenseList;
SuspenseList = React.SuspenseList;
});
function Text(props) {
@ -40,7 +40,6 @@ describe('ReactSuspenseList', () => {
return Component;
}
// @gate experimental
it('warns if an unsupported revealOrder option is used', () => {
function Foo() {
return (
@ -60,7 +59,6 @@ describe('ReactSuspenseList', () => {
]);
});
// @gate experimental
it('warns if a upper case revealOrder option is used', () => {
function Foo() {
return (
@ -80,7 +78,6 @@ describe('ReactSuspenseList', () => {
]);
});
// @gate experimental
it('warns if a misspelled revealOrder option is used', () => {
function Foo() {
return (
@ -101,7 +98,6 @@ describe('ReactSuspenseList', () => {
]);
});
// @gate experimental
it('warns if a single element is passed to a "forwards" list', () => {
function Foo({children}) {
return <SuspenseList revealOrder="forwards">{children}</SuspenseList>;
@ -134,7 +130,6 @@ describe('ReactSuspenseList', () => {
]);
});
// @gate experimental
it('warns if a single fragment is passed to a "backwards" list', () => {
function Foo() {
return (
@ -155,7 +150,6 @@ describe('ReactSuspenseList', () => {
]);
});
// @gate experimental
it('warns if a nested array is passed to a "forwards" list', () => {
function Foo({items}) {
return (
@ -183,7 +177,6 @@ describe('ReactSuspenseList', () => {
]);
});
// @gate experimental
it('shows content independently by default', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -250,7 +243,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('shows content independently in legacy mode regardless of option', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -321,7 +313,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('displays all "together"', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -391,7 +382,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('displays all "together" even when nested as siblings', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -477,7 +467,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('displays all "together" in nested SuspenseLists', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -539,7 +528,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('displays all "together" in nested SuspenseLists where the inner is default', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -599,7 +587,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('displays all "together" during an update', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -684,7 +671,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('avoided boundaries can be coordinate with SuspenseList', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -783,7 +769,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('displays each items in "forwards" order', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -849,7 +834,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('displays each items in "backwards" order', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -915,7 +899,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('displays added row at the top "together" and the bottom in "forwards" order', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -1070,7 +1053,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('displays added row at the top "together" and the bottom in "backwards" order', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -1255,7 +1237,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('switches to rendering fallbacks if the tail takes long CPU time', async () => {
function Foo() {
return (
@ -1275,7 +1256,7 @@ describe('ReactSuspenseList', () => {
// This render is only CPU bound. Nothing suspends.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo />);
});
} else {
@ -1324,7 +1305,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('only shows one loading state at a time for "collapsed" tail insertions', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -1394,7 +1374,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('warns if an unsupported tail option is used', () => {
function Foo() {
return (
@ -1415,7 +1394,6 @@ describe('ReactSuspenseList', () => {
]);
});
// @gate experimental
it('warns if a tail option is used with "together"', () => {
function Foo() {
return (
@ -1436,7 +1414,6 @@ describe('ReactSuspenseList', () => {
]);
});
// @gate experimental
it('renders one "collapsed" fallback even if CPU time elapsed', async () => {
function Foo() {
return (
@ -1459,7 +1436,7 @@ describe('ReactSuspenseList', () => {
// This render is only CPU bound. Nothing suspends.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo />);
});
} else {
@ -1509,7 +1486,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('adding to the middle does not collapse insertions (forwards)', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -1652,7 +1628,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('adding to the middle does not collapse insertions (backwards)', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -1800,7 +1775,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('adding to the middle of committed tail does not collapse insertions', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -1958,7 +1932,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('only shows no initial loading state "hidden" tail insertions', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -2022,7 +1995,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('eventually resolves a nested forwards suspense list', async () => {
const B = createAsyncText('B');
@ -2085,7 +2057,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('eventually resolves a nested forwards suspense list with a hidden tail', async () => {
const B = createAsyncText('B');
@ -2132,7 +2103,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('eventually resolves two nested forwards suspense lists with a hidden tail', async () => {
const B = createAsyncText('B');
@ -2200,7 +2170,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('can do unrelated adjacent updates', async () => {
let updateAdjacent;
function Adjacent() {
@ -2247,7 +2216,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('is able to re-suspend the last rows during an update with hidden', async () => {
const AsyncB = createAsyncText('B');
@ -2336,7 +2304,6 @@ describe('ReactSuspenseList', () => {
expect(previousInst).toBe(setAsyncB);
});
// @gate experimental
it('is able to re-suspend the last rows during an update with hidden', async () => {
const AsyncB = createAsyncText('B');
@ -2425,7 +2392,6 @@ describe('ReactSuspenseList', () => {
expect(previousInst).toBe(setAsyncB);
});
// @gate experimental
it('is able to interrupt a partially rendered tree and continue later', async () => {
const AsyncA = createAsyncText('A');
@ -2462,7 +2428,7 @@ describe('ReactSuspenseList', () => {
await ReactNoop.act(async () => {
// Add a few items at the end.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
updateLowPri(true);
});
} else {
@ -2504,7 +2470,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('can resume class components when revealed together', async () => {
const A = createAsyncText('A');
const B = createAsyncText('B');
@ -2567,7 +2532,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('should be able to progressively show CPU expensive rows with two pass rendering', async () => {
function TwoPass({text}) {
const [pass, setPass] = React.useState(0);
@ -2605,7 +2569,7 @@ describe('ReactSuspenseList', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App />);
});
} else {
@ -2638,7 +2602,6 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental
it('should be able to progressively show rows with two pass rendering and visible', async () => {
function TwoPass({text}) {
const [pass, setPass] = React.useState(0);
@ -2678,7 +2641,7 @@ describe('ReactSuspenseList', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App />);
});
} else {
@ -2720,7 +2683,7 @@ describe('ReactSuspenseList', () => {
);
});
// @gate experimental && enableProfilerTimer
// @gate enableProfilerTimer
it('counts the actual duration when profiling a SuspenseList', async () => {
// Order of parameters: id, phase, actualDuration, treeBaseDuration
const onRender = jest.fn();

View File

@ -212,7 +212,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo />);
});
} else {
@ -284,7 +284,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// The update will suspend.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo renderBar={true} />);
});
} else {
@ -354,7 +354,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYield([]);
// B suspends. Continue rendering the remaining siblings.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<Suspense fallback={<Text text="Loading..." />}>
<Text text="A" />
@ -401,7 +401,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// TODO: Delete this feature flag.
// @gate !replayFailedUnitOfWorkWithInvokeGuardedCallback || !__DEV__
// @gate enableCache
// @gate experimental || !enableSyncDefaultUpdates
it('retries on error', async () => {
class ErrorBoundary extends React.Component {
state = {error: null};
@ -437,7 +436,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([]);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App renderContent={true} />);
});
} else {
@ -567,7 +566,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
});
// @gate enableCache
// @gate experimental || !enableSyncDefaultUpdates
it('keeps working on lower priority work after being pinged', async () => {
// Advance the virtual time so that we're close to the edge of a bucket.
ReactNoop.expire(149);
@ -586,7 +584,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([]);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App showA={true} showB={false} />);
});
} else {
@ -599,7 +597,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// but not enough to expire the suspense timeout.
ReactNoop.expire(120);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App showA={true} showB={true} />);
});
} else {
@ -630,7 +628,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Default pri
ReactNoop.render(<App />);
// Low pri
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App hide={true} />);
});
@ -647,7 +645,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// times model. Might not make sense in the new model.
// TODO: This test doesn't over what it was originally designed to test.
// Either rewrite or delete.
// @gate experimental || !enableSyncDefaultUpdates
it('tries each subsequent level after suspending', async () => {
const root = ReactNoop.createRoot();
@ -683,7 +680,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Schedule an update at several distinct expiration times
await ReactNoop.act(async () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<App step={1} shouldSuspend={true} />);
});
} else {
@ -694,7 +691,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
interrupt();
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<App step={2} shouldSuspend={true} />);
});
} else {
@ -705,7 +702,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
interrupt();
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<App step={3} shouldSuspend={true} />);
});
} else {
@ -928,7 +925,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span('Async'), span('Sync')]);
});
// @gate experimental
// @gate enableCache
it('does not expire for transitions', async () => {
ReactNoop.render(
<Fragment>
@ -937,7 +934,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
);
expect(Scheduler).toFlushAndYield([]);
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<Fragment>
<Suspense fallback={<Text text="Loading..." />}>
@ -984,7 +981,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYield([]);
expect(ReactNoop.getChildren()).toEqual([]);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<>
<Suspense fallback={<Text text="Loading..." />}>
@ -1051,7 +1048,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYield([]);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<Suspense fallback={<Text text="Loading..." />}>
<AsyncText text="Async" />
@ -1075,7 +1072,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span('Async')]);
});
// @gate experimental
// @gate enableCache
it('starts working on an update even if its priority falls between two suspended levels', async () => {
function App(props) {
@ -1096,7 +1092,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYield(['S']);
// Schedule an update, and suspend for up to 5 seconds.
React.unstable_startTransition(() => ReactNoop.render(<App text="A" />));
React.startTransition(() => ReactNoop.render(<App text="A" />));
// The update should suspend.
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
expect(ReactNoop.getChildren()).toEqual([span('S')]);
@ -1108,7 +1104,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span('S')]);
// Schedule another low priority update.
React.unstable_startTransition(() => ReactNoop.render(<App text="B" />));
React.startTransition(() => ReactNoop.render(<App text="B" />));
// This update should also suspend.
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
expect(ReactNoop.getChildren()).toEqual([span('S')]);
@ -1857,7 +1853,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
});
// @gate enableCache
// @gate experimental || !enableSyncDefaultUpdates
it('suspends for longer if something took a long (CPU bound) time to render', async () => {
function Foo({renderContent}) {
Scheduler.unstable_yieldValue('Foo');
@ -1872,7 +1867,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYield(['Foo']);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo renderContent={true} />);
});
} else {
@ -2044,7 +2039,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYield(['Foo']);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo renderContent={true} />);
});
} else {
@ -2365,7 +2360,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span('A')]);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo showB={true} />);
});
} else {
@ -2445,7 +2440,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
});
describe('startTransition', () => {
// @gate experimental
// @gate enableCache
it('top level render', async () => {
function App({page}) {
@ -2457,7 +2451,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
}
// Initial render.
React.unstable_startTransition(() => ReactNoop.render(<App page="A" />));
React.startTransition(() => ReactNoop.render(<App page="A" />));
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
// Only a short time is needed to unsuspend the initial loading state.
@ -2471,7 +2465,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span('A')]);
// Start transition.
React.unstable_startTransition(() => ReactNoop.render(<App page="B" />));
React.startTransition(() => ReactNoop.render(<App page="B" />));
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
Scheduler.unstable_advanceTime(100000);
@ -2485,7 +2479,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span('B')]);
});
// @gate experimental
// @gate enableCache
it('hooks', async () => {
let transitionToPage;
@ -2507,7 +2500,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Initial render.
await ReactNoop.act(async () => {
React.unstable_startTransition(() => transitionToPage('A'));
React.startTransition(() => transitionToPage('A'));
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
// Only a short time is needed to unsuspend the initial loading state.
@ -2523,7 +2516,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Start transition.
await ReactNoop.act(async () => {
React.unstable_startTransition(() => transitionToPage('B'));
React.startTransition(() => transitionToPage('B'));
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
Scheduler.unstable_advanceTime(100000);
@ -2538,7 +2531,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span('B')]);
});
// @gate experimental
// @gate enableCache
it('classes', async () => {
let transitionToPage;
@ -2563,7 +2555,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Initial render.
await ReactNoop.act(async () => {
React.unstable_startTransition(() => transitionToPage('A'));
React.startTransition(() => transitionToPage('A'));
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
// Only a short time is needed to unsuspend the initial loading state.
@ -2579,7 +2571,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Start transition.
await ReactNoop.act(async () => {
React.unstable_startTransition(() => transitionToPage('B'));
React.startTransition(() => transitionToPage('B'));
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
Scheduler.unstable_advanceTime(100000);
@ -2596,7 +2588,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
});
describe('delays transitions when using React.startTranistion', () => {
// @gate experimental
// @gate enableCache
it('top level render', async () => {
function App({page}) {
@ -2608,7 +2599,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
}
// Initial render.
React.unstable_startTransition(() => ReactNoop.render(<App page="A" />));
React.startTransition(() => ReactNoop.render(<App page="A" />));
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
// Only a short time is needed to unsuspend the initial loading state.
@ -2622,7 +2613,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span('A')]);
// Start transition.
React.unstable_startTransition(() => ReactNoop.render(<App page="B" />));
React.startTransition(() => ReactNoop.render(<App page="B" />));
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
Scheduler.unstable_advanceTime(2999);
@ -2637,7 +2628,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span('B')]);
// Start a long (infinite) transition.
React.unstable_startTransition(() => ReactNoop.render(<App page="C" />));
React.startTransition(() => ReactNoop.render(<App page="C" />));
expect(Scheduler).toFlushAndYield(['Suspend! [C]', 'Loading...']);
// Even after lots of time has passed, we have still not yet flushed the
@ -2647,7 +2638,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span('B')]);
});
// @gate experimental
// @gate enableCache
it('hooks', async () => {
let transitionToPage;
@ -2669,7 +2659,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Initial render.
await ReactNoop.act(async () => {
React.unstable_startTransition(() => transitionToPage('A'));
React.startTransition(() => transitionToPage('A'));
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
// Only a short time is needed to unsuspend the initial loading state.
@ -2685,7 +2675,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Start transition.
await ReactNoop.act(async () => {
React.unstable_startTransition(() => transitionToPage('B'));
React.startTransition(() => transitionToPage('B'));
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
@ -2703,7 +2693,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Start a long (infinite) transition.
await ReactNoop.act(async () => {
React.unstable_startTransition(() => transitionToPage('C'));
React.startTransition(() => transitionToPage('C'));
expect(Scheduler).toFlushAndYield(['Suspend! [C]', 'Loading...']);
@ -2715,7 +2705,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
});
});
// @gate experimental
// @gate enableCache
it('classes', async () => {
let transitionToPage;
@ -2740,7 +2729,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Initial render.
await ReactNoop.act(async () => {
React.unstable_startTransition(() => transitionToPage('A'));
React.startTransition(() => transitionToPage('A'));
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
// Only a short time is needed to unsuspend the initial loading state.
@ -2756,7 +2745,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Start transition.
await ReactNoop.act(async () => {
React.unstable_startTransition(() => transitionToPage('B'));
React.startTransition(() => transitionToPage('B'));
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
Scheduler.unstable_advanceTime(2999);
@ -2773,7 +2762,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Start a long (infinite) transition.
await ReactNoop.act(async () => {
React.unstable_startTransition(() => transitionToPage('C'));
React.startTransition(() => transitionToPage('C'));
expect(Scheduler).toFlushAndYield(['Suspend! [C]', 'Loading...']);
@ -2786,7 +2775,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
});
});
// @gate experimental
// @gate enableCache
it('do not show placeholder when updating an avoided boundary with startTransition', async () => {
function App({page}) {
@ -2810,7 +2798,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span('Hi!'), span('A')]);
// Start transition.
React.unstable_startTransition(() => ReactNoop.render(<App page="B" />));
React.startTransition(() => ReactNoop.render(<App page="B" />));
expect(Scheduler).toFlushAndYield(['Hi!', 'Suspend! [B]', 'Loading B...']);
@ -2831,7 +2819,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
);
});
// @gate experimental
// @gate enableCache
it('do not show placeholder when mounting an avoided boundary with startTransition', async () => {
function App({page}) {
@ -2857,7 +2844,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span('Hi!'), span('A')]);
// Start transition.
React.unstable_startTransition(() => ReactNoop.render(<App page="B" />));
React.startTransition(() => ReactNoop.render(<App page="B" />));
expect(Scheduler).toFlushAndYield(['Hi!', 'Suspend! [B]', 'Loading B...']);
@ -2913,7 +2900,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Update. Since showing a fallback would hide content that's already
// visible, it should suspend for a JND without committing.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<App text="First update" />);
});
} else {
@ -2926,7 +2913,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Update again. This should also suspend for a JND.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<App text="Second update" />);
});
} else {
@ -2992,7 +2979,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(root).toMatchRenderedOutput(<span prop="Foo" />);
});
// @gate experimental
// @gate enableCache
it('should not render hidden content while suspended on higher pri', async () => {
function Offscreen() {
@ -3021,7 +3007,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop).toMatchRenderedOutput(<div hidden={true} />);
// Start transition.
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App showContent={true} />);
});
@ -3043,7 +3029,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
);
});
// @gate experimental
// @gate enableCache
it('should be able to unblock higher pri content before suspended hidden', async () => {
function Offscreen() {
@ -3074,7 +3059,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYieldThrough(['Suspend! [A]']);
// Start transition.
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<App showContent={true} />);
});
@ -3272,7 +3257,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// update even though the primary tree is suspended.
await ReactNoop.act(async () => {
setAppText('C');
React.unstable_startTransition(() => {
React.startTransition(() => {
setFallbackText('Still loading...');
});
});
@ -3705,11 +3690,10 @@ describe('ReactSuspenseWithNoopRenderer', () => {
);
});
// @gate experimental
// @gate enableCache
// @gate !enableSyncDefaultUpdates
it('regression: ping at high priority causes update to be dropped', async () => {
const {useState, unstable_useTransition: useTransition} = React;
const {useState, useTransition} = React;
let setTextA;
function A() {
@ -3818,15 +3802,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
});
// Regression: https://github.com/facebook/react/issues/18486
// @gate experimental
// @gate enableCache
it('does not get stuck in pending state with render phase updates', async () => {
let setTextWithShortTransition;
let setTextWithLongTransition;
function App() {
const [isPending1, startShortTransition] = React.unstable_useTransition();
const [isPending2, startLongTransition] = React.unstable_useTransition();
const [isPending1, startShortTransition] = React.useTransition();
const [isPending2, startLongTransition] = React.useTransition();
const isPending = isPending1 || isPending2;
const [text, setText] = React.useState('');
const [mirror, setMirror] = React.useState('');

View File

@ -32,9 +32,9 @@ describe('ReactTransition', () => {
Scheduler = require('scheduler');
useState = React.useState;
useLayoutEffect = React.useLayoutEffect;
useTransition = React.unstable_useTransition;
useTransition = React.useTransition;
Suspense = React.Suspense;
startTransition = React.unstable_startTransition;
startTransition = React.startTransition;
getCacheForType = React.unstable_getCacheForType;
act = ReactNoop.act;
@ -158,7 +158,6 @@ describe('ReactTransition', () => {
}
}
// @gate experimental
// @gate enableCache
test('isPending works even if called from outside an input event', async () => {
let start;
@ -200,7 +199,6 @@ describe('ReactTransition', () => {
expect(root).toMatchRenderedOutput('Async');
});
// @gate experimental
// @gate enableCache
test(
'when multiple transitions update the same queue, only the most recent ' +
@ -320,7 +318,6 @@ describe('ReactTransition', () => {
);
// Same as previous test, but for class update queue.
// @gate experimental
// @gate enableCache
test(
'when multiple transitions update the same queue, only the most recent ' +
@ -445,7 +442,6 @@ describe('ReactTransition', () => {
},
);
// @gate experimental
// @gate enableCache
test(
'when multiple transitions update overlapping queues, all the transitions ' +
@ -551,7 +547,6 @@ describe('ReactTransition', () => {
},
);
// @gate experimental
// @gate enableCache
test('interrupt a refresh transition if a new transition is scheduled', async () => {
const root = ReactNoop.createRoot();
@ -607,7 +602,6 @@ describe('ReactTransition', () => {
expect(root).toMatchRenderedOutput('Updated');
});
// @gate experimental
// @gate enableCache
test(
"interrupt a refresh transition when something suspends and we've " +
@ -669,7 +663,7 @@ describe('ReactTransition', () => {
expect(Scheduler).toFlushAndYieldThrough(['A']);
// Now schedule a second transition. We won't interrupt the first one.
React.unstable_startTransition(() => {
React.startTransition(() => {
setShouldHideInParent(true);
});
// Continue rendering the first transition.
@ -710,7 +704,6 @@ describe('ReactTransition', () => {
},
);
// @gate experimental
// @gate enableCache
test(
'interrupt a refresh transition when something suspends and a parent ' +
@ -776,8 +769,6 @@ describe('ReactTransition', () => {
},
);
// @gate experimental
// @gate enableCache
it('should render normal pri updates scheduled after transitions before transitions', async () => {
let updateTransitionPri;
let updateNormalPri;
@ -833,7 +824,6 @@ describe('ReactTransition', () => {
expect(root).toMatchRenderedOutput('Transition pri: 1, Normal pri: 1');
});
// @gate experimental
// @gate enableCache
it('should render normal pri updates before transition suspense retries', async () => {
let updateTransitionPri;
@ -898,8 +888,6 @@ describe('ReactTransition', () => {
expect(root).toMatchRenderedOutput('Async, Normal pri: 1');
});
// @gate experimental
// @gate enableCache
it('should not interrupt transitions with normal pri updates', async () => {
let updateNormalPri;
let updateTransitionPri;

View File

@ -15,7 +15,7 @@ describe('ReactUpdatePriority', () => {
Scheduler = require('scheduler');
ContinuousEventPriority = require('react-reconciler/constants')
.ContinuousEventPriority;
startTransition = React.unstable_startTransition;
startTransition = React.startTransition;
useState = React.useState;
useEffect = React.useEffect;
});
@ -84,7 +84,6 @@ describe('ReactUpdatePriority', () => {
expect(Scheduler).toHaveYielded(['Idle: 2, Default: 2']);
});
// @gate experimental
test('continuous updates should interrupt transisions', async () => {
const root = ReactNoop.createRoot();

View File

@ -153,7 +153,6 @@ describe('updaters', () => {
expect(allSchedulerTypes).toEqual([[null], [SchedulingComponent]]);
});
// @gate experimental
it('should cover cascading updates', async () => {
let triggerActiveCascade = null;
let triggerPassiveCascade = null;
@ -183,7 +182,7 @@ describe('updaters', () => {
return count;
};
const root = ReactDOM.unstable_createRoot(document.createElement('div'));
const root = ReactDOM.createRoot(document.createElement('div'));
await ReactTestUtils.act(async () => {
root.render(<Parent />);
expect(Scheduler).toFlushAndYieldThrough([
@ -292,7 +291,6 @@ describe('updaters', () => {
done();
});
// @gate experimental
it('should cover error handling', async () => {
let triggerError = null;
@ -329,7 +327,7 @@ describe('updaters', () => {
throw new Error('Hello');
};
const root = ReactDOM.unstable_createRoot(document.createElement('div'));
const root = ReactDOM.createRoot(document.createElement('div'));
await ReactTestUtils.act(async () => {
root.render(<Parent shouldError={false} />);
});
@ -349,7 +347,6 @@ describe('updaters', () => {
Scheduler.unstable_flushAll();
});
// @gate experimental
it('should distinguish between updaters in the case of interleaved work', async () => {
const {
FunctionComponent,
@ -368,7 +365,7 @@ describe('updaters', () => {
const LowPriorityUpdater = () => {
const [count, setCount] = React.useState(0);
triggerLowPriorityUpdate = () => {
React.unstable_startTransition(() => {
React.startTransition(() => {
setCount(prevCount => prevCount + 1);
});
};
@ -380,7 +377,7 @@ describe('updaters', () => {
return null;
};
const root = ReactDOM.unstable_createRoot(document.createElement('div'));
const root = ReactDOM.createRoot(document.createElement('div'));
root.render(
<React.Fragment>
<SyncPriorityUpdater />

View File

@ -149,7 +149,6 @@ describe('SchedulingProfiler', () => {
});
// @gate enableSchedulingProfiler
// @gate experimental || !enableSyncDefaultUpdates
it('should mark render yields', async () => {
function Bar() {
Scheduler.unstable_yieldValue('Bar');
@ -162,7 +161,7 @@ describe('SchedulingProfiler', () => {
}
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(<Foo />);
});

View File

@ -100,7 +100,6 @@ describe('SchedulingProfiler labels', () => {
);
});
// @gate experimental
// @gate enableSchedulingProfiler
it('regression test DefaultLane', () => {
const container = document.createElement('div');
@ -114,7 +113,6 @@ describe('SchedulingProfiler labels', () => {
});
});
// @gate experimental
// @gate enableSchedulingProfiler
// @gate !enableLegacyFBSupport
it('regression test InputDiscreteLane', () => {
@ -144,7 +142,6 @@ describe('SchedulingProfiler labels', () => {
);
});
// @gate experimental
// @gate enableSchedulingProfiler
it('regression test InputContinuousLane', () => {
const container = document.createElement('div');

View File

@ -31,8 +31,11 @@ function loadModules() {
ReactNoop = require('react-noop-renderer');
Scheduler = require('scheduler');
act = ReactNoop.act;
createMutableSource = React.unstable_createMutableSource;
useMutableSource = React.unstable_useMutableSource;
// Stable entrypoints export with "unstable_" prefix.
createMutableSource =
React.createMutableSource || React.unstable_createMutableSource;
useMutableSource = React.useMutableSource || React.unstable_useMutableSource;
}
describe('useMutableSource', () => {
@ -138,7 +141,6 @@ describe('useMutableSource', () => {
beforeEach(loadModules);
// @gate experimental
it('should subscribe to a source and schedule updates when it changes', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -206,14 +208,13 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should restart work if a new source is mutated during render', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
act(() => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<>
<Component
@ -262,7 +263,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should schedule an update if a new source is mutated between render and commit (subscription)', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -302,7 +302,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should unsubscribe and resubscribe if a new source is used', () => {
const sourceA = createSource('a-one');
const mutableSourceA = createMutableSource(
@ -359,7 +358,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should unsubscribe and resubscribe if a new subscribe function is provided', () => {
const source = createSource('a-one');
const mutableSource = createMutableSource(source, param => param.version);
@ -424,7 +422,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should re-use previously read snapshot value when reading is unsafe', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -452,7 +449,7 @@ describe('useMutableSource', () => {
// Changing values should schedule an update with React.
// Start working on this update but don't finish it.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
source.value = 'two';
});
} else {
@ -487,7 +484,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should read from source on newly mounted subtree if no pending updates are scheduled for source', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -527,7 +523,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should throw and restart render if source and snapshot are unavailable during an update', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -591,7 +586,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should throw and restart render if source and snapshot are unavailable during a sync update', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -655,7 +649,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should only update components whose subscriptions fire', () => {
const source = createComplexSource('a:one', 'b:one');
const mutableSource = createMutableSource(source, param => param.version);
@ -694,7 +687,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should detect tearing in part of the store not yet subscribed to', () => {
const source = createComplexSource('a:one', 'b:one');
const mutableSource = createMutableSource(source, param => param.version);
@ -722,7 +714,7 @@ describe('useMutableSource', () => {
// Because the store has not changed yet, there are no pending updates,
// so it is considered safe to read from when we start this render.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<>
<Component
@ -787,7 +779,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('does not schedule an update for subscriptions that fire with an unchanged snapshot', () => {
const MockComponent = jest.fn(Component);
@ -814,7 +805,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should throw and restart if getSnapshot changes between scheduled update and re-render', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -855,7 +845,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should recover from a mutation during yield when other work is scheduled', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -863,7 +852,7 @@ describe('useMutableSource', () => {
act(() => {
// Start a render that uses the mutable source.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<>
<Component
@ -910,7 +899,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should not throw if the new getSnapshot returns the same snapshot value', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -965,7 +953,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should not throw if getSnapshot changes but the source can be safely read from anyway', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -1005,7 +992,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should still schedule an update if an eager selector throws after a mutation', () => {
const source = createSource({
friends: [
@ -1072,7 +1058,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should not warn about updates that fire between unmount and passive unsubscribe', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -1109,7 +1094,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should support inline selectors and updates that are processed after selector change', async () => {
const source = createSource({
a: 'initial',
@ -1154,7 +1138,6 @@ describe('useMutableSource', () => {
expect(root).toMatchRenderedOutput('Another update');
});
// @gate experimental
it('should clear the update queue when getSnapshot changes with pending lower priority updates', async () => {
const source = createSource({
a: 'initial',
@ -1211,7 +1194,6 @@ describe('useMutableSource', () => {
expect(root).toMatchRenderedOutput('B: Update');
});
// @gate experimental
it('should clear the update queue when source changes with pending lower priority updates', async () => {
const sourceA = createSource('initial');
const sourceB = createSource('initial');
@ -1256,7 +1238,6 @@ describe('useMutableSource', () => {
expect(root).toMatchRenderedOutput('B: Update');
});
// @gate experimental
it('should always treat reading as potentially unsafe when getSnapshot changes between renders', async () => {
const source = createSource({
a: 'foo',
@ -1346,7 +1327,6 @@ describe('useMutableSource', () => {
expect(Scheduler).toHaveYielded(['x: bar, y: bar']);
});
// @gate experimental
it('getSnapshot changes and then source is mutated in between paint and passive effect phase', async () => {
const source = createSource({
a: 'foo',
@ -1405,7 +1385,6 @@ describe('useMutableSource', () => {
expect(root).toMatchRenderedOutput('baz');
});
// @gate experimental
it('getSnapshot changes and then source is mutated in between paint and passive effect phase, case 2', async () => {
const source = createSource({
a: 'a0',
@ -1476,7 +1455,6 @@ describe('useMutableSource', () => {
expect(root.getChildrenAsJSX()).toEqual('first: a1, second: a1');
});
// @gate experimental
it(
'if source is mutated after initial read but before subscription is set ' +
'up, should still entangle all pending mutations even if snapshot of ' +
@ -1533,7 +1511,7 @@ describe('useMutableSource', () => {
await act(async () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(
<>
<Read getSnapshot={getSnapshotA} />
@ -1563,7 +1541,7 @@ describe('useMutableSource', () => {
// read during render will happen to match the latest value. But it should
// still entangle the updates to prevent the previous update (a1) from
// rendering by itself.
React.unstable_startTransition(() => {
React.startTransition(() => {
mutateA('a0');
mutateB('b0');
});
@ -1581,7 +1559,6 @@ describe('useMutableSource', () => {
},
);
// @gate experimental
it('warns about functions being used as snapshot values', async () => {
const source = createSource(() => 'a');
const mutableSource = createMutableSource(source, param => param.version);
@ -1609,7 +1586,6 @@ describe('useMutableSource', () => {
expect(root).toMatchRenderedOutput('a');
});
// @gate experimental
it('getSnapshot changes and then source is mutated during interleaved event', async () => {
const {useEffect} = React;
@ -1680,7 +1656,7 @@ describe('useMutableSource', () => {
await act(async () => {
// Switch the parent and the child to read using the same config
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<App parentConfig={configB} childConfig={configB} />);
});
} else {
@ -1692,7 +1668,7 @@ describe('useMutableSource', () => {
// Mutate the config. This is at lower priority so that 1) to make sure
// it doesn't happen to get batched with the in-progress render, and 2)
// so it doesn't interrupt the in-progress render.
React.unstable_startTransition(() => {
React.startTransition(() => {
source.valueB = '3';
});
@ -1734,7 +1710,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should not tear with newly mounted component when updates were scheduled at a lower priority', async () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -1802,7 +1777,7 @@ describe('useMutableSource', () => {
expect(source.listenerCount).toBe(1);
// Mutate -> schedule update for ComponentA
React.unstable_startTransition(() => {
React.startTransition(() => {
source.value = 'two';
});
@ -1815,7 +1790,6 @@ describe('useMutableSource', () => {
if (__DEV__) {
// See https://github.com/facebook/react/issues/19948
describe('side effecte detection', () => {
// @gate experimental
it('should throw if a mutable source is mutated during render', () => {
const source = createSource(0);
const mutableSource = createMutableSource(
@ -1860,7 +1834,6 @@ describe('useMutableSource', () => {
]);
});
// @gate experimental
it('should throw if a mutable source is mutated during render (legacy mode)', () => {
const source = createSource('initial');
const mutableSource = createMutableSource(
@ -1899,7 +1872,6 @@ describe('useMutableSource', () => {
expect(Scheduler).toHaveYielded(['MutateDuringRead:initial']);
});
// @gate experimental
it('should not misidentify mutations after render as side effects', async () => {
const source = createSource('initial');
const mutableSource = createMutableSource(
@ -1934,7 +1906,6 @@ describe('useMutableSource', () => {
});
describe('dev warnings', () => {
// @gate experimental
it('should warn if the subscribe function does not return an unsubscribe function', () => {
const source = createSource('one');
const mutableSource = createMutableSource(
@ -1960,7 +1931,6 @@ describe('useMutableSource', () => {
);
});
// @gate experimental
it('should error if multiple renderers of the same type use a mutable source at the same time', () => {
const source = createSource('one');
const mutableSource = createMutableSource(
@ -1971,7 +1941,7 @@ describe('useMutableSource', () => {
act(() => {
// Start a render that uses the mutable source.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<>
<Component
@ -2041,7 +2011,6 @@ describe('useMutableSource', () => {
});
});
// @gate experimental
it('should error if multiple renderers of the same type use a mutable source at the same time with mutation between', () => {
const source = createSource('one');
const mutableSource = createMutableSource(
@ -2052,7 +2021,7 @@ describe('useMutableSource', () => {
act(() => {
// Start a render that uses the mutable source.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactNoop.render(
<>
<Component

View File

@ -27,8 +27,12 @@ describe('useMutableSourceHydration', () => {
Scheduler = require('scheduler');
act = require('react-dom/test-utils').unstable_concurrentAct;
createMutableSource = React.unstable_createMutableSource;
useMutableSource = React.unstable_useMutableSource;
// Stable entrypoints export with "unstable_" prefix.
createMutableSource =
React.createMutableSource || React.unstable_createMutableSource;
useMutableSource =
React.useMutableSource || React.unstable_useMutableSource;
});
function dispatchAndSetCurrentEvent(el, event) {
@ -140,7 +144,6 @@ describe('useMutableSourceHydration', () => {
return <div>{`${label}:${snapshot}`}</div>;
}
// @gate experimental
it('should render and hydrate', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -164,7 +167,7 @@ describe('useMutableSourceHydration', () => {
expect(Scheduler).toHaveYielded(['only:one']);
expect(source.listenerCount).toBe(0);
const root = ReactDOM.unstable_createRoot(container, {
const root = ReactDOM.createRoot(container, {
hydrate: true,
hydrationOptions: {
mutableSources: [mutableSource],
@ -177,7 +180,6 @@ describe('useMutableSourceHydration', () => {
expect(source.listenerCount).toBe(1);
});
// @gate experimental
it('should detect a tear before hydrating a component', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -201,7 +203,7 @@ describe('useMutableSourceHydration', () => {
expect(Scheduler).toHaveYielded(['only:one']);
expect(source.listenerCount).toBe(0);
const root = ReactDOM.unstable_createRoot(container, {
const root = ReactDOM.createRoot(container, {
hydrate: true,
hydrationOptions: {
mutableSources: [mutableSource],
@ -222,7 +224,6 @@ describe('useMutableSourceHydration', () => {
expect(source.listenerCount).toBe(1);
});
// @gate experimental
it('should detect a tear between hydrating components', () => {
const source = createSource('one');
const mutableSource = createMutableSource(source, param => param.version);
@ -254,7 +255,7 @@ describe('useMutableSourceHydration', () => {
expect(Scheduler).toHaveYielded(['a:one', 'b:one']);
expect(source.listenerCount).toBe(0);
const root = ReactDOM.unstable_createRoot(container, {
const root = ReactDOM.createRoot(container, {
hydrate: true,
hydrationOptions: {
mutableSources: [mutableSource],
@ -263,7 +264,7 @@ describe('useMutableSourceHydration', () => {
expect(() => {
act(() => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<TestComponent />);
});
} else {
@ -281,7 +282,6 @@ describe('useMutableSourceHydration', () => {
expect(source.listenerCount).toBe(2);
});
// @gate experimental
it('should detect a tear between hydrating components reading from different parts of a source', () => {
const source = createComplexSource('a:one', 'b:one');
const mutableSource = createMutableSource(source, param => param.version);
@ -314,7 +314,7 @@ describe('useMutableSourceHydration', () => {
container.innerHTML = htmlString;
expect(Scheduler).toHaveYielded(['0:a:one', '1:b:one']);
const root = ReactDOM.unstable_createRoot(container, {
const root = ReactDOM.createRoot(container, {
hydrate: true,
hydrationOptions: {
mutableSources: [mutableSource],
@ -323,7 +323,7 @@ describe('useMutableSourceHydration', () => {
expect(() => {
act(() => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(
<>
<Component
@ -370,7 +370,6 @@ describe('useMutableSourceHydration', () => {
expect(Scheduler).toHaveYielded(['0:a:one', '1:b:two']);
});
// @gate experimental
// @gate !enableSyncDefaultUpdates
it('should detect a tear during a higher priority interruption', () => {
const source = createSource('one');
@ -405,7 +404,7 @@ describe('useMutableSourceHydration', () => {
expect(Scheduler).toHaveYielded([1, 'a:one']);
expect(source.listenerCount).toBe(0);
const root = ReactDOM.unstable_createRoot(container, {
const root = ReactDOM.createRoot(container, {
hydrate: true,
hydrationOptions: {
mutableSources: [mutableSource],
@ -415,7 +414,7 @@ describe('useMutableSourceHydration', () => {
expect(() => {
act(() => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.render(<TestComponent flag={1} />);
});
} else {

View File

@ -2437,7 +2437,7 @@ describe('ReactFresh', () => {
};
});
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<AppV1 offscreen={true} />);
expect(Scheduler).toFlushAndYieldThrough(['App#layout']);
const el = container.firstChild;

View File

@ -72,7 +72,6 @@ describe('ReactFlightDOMRelay', () => {
});
});
// @gate experimental
it('can render a client component using a module reference and render there', () => {
function UserClient(props) {
return (
@ -105,7 +104,6 @@ describe('ReactFlightDOMRelay', () => {
expect(container.innerHTML).toEqual('<span>Hello, Seb Smith</span>');
});
// @gate experimental
it('can reasonably handle different element types', () => {
const {
forwardRef,

View File

@ -128,7 +128,6 @@ describe('ReactFlightDOM', () => {
});
});
// @gate experimental
it('should resolve the root', async () => {
const {Suspense} = React;
@ -171,7 +170,7 @@ describe('ReactFlightDOM', () => {
const response = ReactServerDOMReader.createFromReadableStream(readable);
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
await act(async () => {
root.render(<App response={response} />);
});
@ -180,7 +179,6 @@ describe('ReactFlightDOM', () => {
);
});
// @gate experimental
it('should not get confused by $', async () => {
const {Suspense} = React;
@ -210,14 +208,13 @@ describe('ReactFlightDOM', () => {
const response = ReactServerDOMReader.createFromReadableStream(readable);
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
await act(async () => {
root.render(<App response={response} />);
});
expect(container.innerHTML).toBe('<p>$1</p>');
});
// @gate experimental
it('should not get confused by @', async () => {
const {Suspense} = React;
@ -247,14 +244,13 @@ describe('ReactFlightDOM', () => {
const response = ReactServerDOMReader.createFromReadableStream(readable);
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
await act(async () => {
root.render(<App response={response} />);
});
expect(container.innerHTML).toBe('<p>@div</p>');
});
// @gate experimental
it('should progressively reveal server components', async () => {
let reportedErrors = [];
const {Suspense} = React;
@ -383,7 +379,7 @@ describe('ReactFlightDOM', () => {
const response = ReactServerDOMReader.createFromReadableStream(readable);
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
await act(async () => {
root.render(
<Suspense fallback={<p>(loading)</p>}>
@ -454,7 +450,6 @@ describe('ReactFlightDOM', () => {
expect(reportedErrors).toEqual([]);
});
// @gate experimental
it('should preserve state of client components on refetch', async () => {
const {Suspense} = React;
@ -483,7 +478,7 @@ describe('ReactFlightDOM', () => {
}
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
const stream1 = getTestStream();
ReactServerDOMWriter.pipeToNodeWritable(

View File

@ -73,7 +73,6 @@ describe('ReactTestRendererAsync', () => {
expect(renderer.toJSON()).toEqual(['A:2', 'B:2', 'C:2']);
});
// @gate experimental || !enableSyncDefaultUpdates
it('flushThrough flushes until the expected values is yielded', () => {
function Child(props) {
Scheduler.unstable_yieldValue(props.children);
@ -91,7 +90,7 @@ describe('ReactTestRendererAsync', () => {
let renderer;
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
renderer = ReactTestRenderer.create(<Parent step={1} />, {
unstable_isConcurrent: true,
});
@ -112,7 +111,6 @@ describe('ReactTestRendererAsync', () => {
expect(renderer.toJSON()).toEqual(['A:1', 'B:1', 'C:1']);
});
// @gate experimental || !enableSyncDefaultUpdates
it('supports high priority interruptions', () => {
function Child(props) {
Scheduler.unstable_yieldValue(props.children);
@ -138,7 +136,7 @@ describe('ReactTestRendererAsync', () => {
let renderer;
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
renderer = ReactTestRenderer.create(<Example step={1} />, {
unstable_isConcurrent: true,
});

View File

@ -8,55 +8,52 @@
*/
export {
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
Children,
createRef,
Component,
Fragment,
Profiler,
PureComponent,
StrictMode,
Suspense,
SuspenseList,
SuspenseList as unstable_SuspenseList, // TODO: Remove once call sights updated to SuspenseList
cloneElement,
createContext,
createElement,
createFactory,
createMutableSource,
createMutableSource as unstable_createMutableSource,
createRef,
forwardRef,
isValidElement,
lazy,
memo,
startTransition,
startTransition as unstable_startTransition, // TODO: Remove once call sights updated to startTransition
unstable_Cache,
unstable_DebugTracingMode,
unstable_LegacyHidden,
unstable_Scope,
unstable_getCacheForType,
unstable_useCacheRefresh,
unstable_useOpaqueIdentifier,
useCallback,
useContext,
useDebugValue,
useDeferredValue,
useDeferredValue as unstable_useDeferredValue, // TODO: Remove once call sights updated to useDeferredValue
useEffect,
useImperativeHandle,
useDebugValue,
useLayoutEffect,
useMemo,
useMutableSource,
useMutableSource as unstable_useMutableSource,
useReducer,
useRef,
useState,
useMutableSource,
useMutableSource as unstable_useMutableSource,
createMutableSource,
createMutableSource as unstable_createMutableSource,
Fragment,
Profiler,
StrictMode,
Suspense,
unstable_LegacyHidden,
createElement,
cloneElement,
isValidElement,
version,
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
createFactory,
// exposeConcurrentModeAPIs
useTransition,
useTransition as unstable_useTransition,
useDeferredValue,
useDeferredValue as unstable_useDeferredValue,
startTransition,
startTransition as unstable_startTransition,
SuspenseList,
SuspenseList as unstable_SuspenseList,
unstable_getCacheForType,
unstable_Cache,
unstable_useCacheRefresh,
// enableScopeAPI
unstable_Scope,
unstable_useOpaqueIdentifier,
// enableDebugTracing
unstable_DebugTracingMode,
useTransition as unstable_useTransition, // TODO: Remove once call sights updated to useTransition
version,
} from './src/React';
export {jsx, jsxs, jsxDEV} from './src/jsx/ReactJSX';

View File

@ -8,46 +8,44 @@
*/
export {
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
Children,
createRef,
Component,
Fragment,
Profiler,
PureComponent,
StrictMode,
Suspense,
SuspenseList,
cloneElement,
createContext,
createElement,
createFactory,
createMutableSource as unstable_createMutableSource,
createRef,
forwardRef,
isValidElement,
lazy,
memo,
startTransition,
unstable_Cache,
unstable_DebugTracingMode,
unstable_LegacyHidden,
unstable_getCacheForType,
unstable_useCacheRefresh,
unstable_useOpaqueIdentifier,
useCallback,
useContext,
useDebugValue,
useDeferredValue,
useEffect,
useImperativeHandle,
useDebugValue,
useLayoutEffect,
useMemo,
useMutableSource as unstable_useMutableSource,
useReducer,
useRef,
useState,
useMutableSource as unstable_useMutableSource,
createMutableSource as unstable_createMutableSource,
Fragment,
Profiler,
StrictMode,
Suspense,
unstable_LegacyHidden,
createElement,
cloneElement,
isValidElement,
useTransition,
version,
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
createFactory,
// exposeConcurrentModeAPIs
useTransition as unstable_useTransition,
useDeferredValue as unstable_useDeferredValue,
startTransition as unstable_startTransition,
SuspenseList as unstable_SuspenseList,
unstable_useOpaqueIdentifier,
unstable_getCacheForType,
unstable_Cache,
unstable_useCacheRefresh,
// enableDebugTracing
unstable_DebugTracingMode,
} from './src/React';

View File

@ -32,51 +32,45 @@ export type ChildrenArray<+T> = $ReadOnlyArray<ChildrenArray<T>> | T;
// Export all exports so that they're available in tests.
// We can't use export * from in Flow for some reason.
export {
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
Children,
createRef,
Component,
Fragment,
Profiler,
PureComponent,
StrictMode,
Suspense,
SuspenseList,
cloneElement,
createContext,
createElement,
createFactory,
createMutableSource,
createRef,
forwardRef,
isValidElement,
lazy,
memo,
startTransition,
unstable_Cache,
unstable_DebugTracingMode,
unstable_LegacyHidden,
unstable_Scope,
unstable_getCacheForType,
unstable_useCacheRefresh,
unstable_useOpaqueIdentifier,
useCallback,
useContext,
useDebugValue,
useDeferredValue,
useEffect,
useImperativeHandle,
useDebugValue,
useLayoutEffect,
useMemo,
useMutableSource,
useReducer,
useRef,
useState,
useMutableSource,
useMutableSource as unstable_useMutableSource,
createMutableSource,
createMutableSource as unstable_createMutableSource,
Fragment,
Profiler,
unstable_DebugTracingMode,
StrictMode,
Suspense,
createElement,
cloneElement,
isValidElement,
version,
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
createFactory,
useTransition,
useTransition as unstable_useTransition,
startTransition,
startTransition as unstable_startTransition,
useDeferredValue,
useDeferredValue as unstable_useDeferredValue,
SuspenseList,
SuspenseList as unstable_SuspenseList,
unstable_LegacyHidden,
unstable_Scope,
unstable_useOpaqueIdentifier,
unstable_getCacheForType,
unstable_Cache,
unstable_useCacheRefresh,
version,
} from './src/React';

View File

@ -8,54 +8,51 @@
*/
export {
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
Children,
createRef,
Component,
Fragment,
Profiler,
PureComponent,
StrictMode,
Suspense,
SuspenseList,
SuspenseList as unstable_SuspenseList, // TODO: Remove once call sights updated to SuspenseList
cloneElement,
createContext,
createElement,
createMutableSource,
createMutableSource as unstable_createMutableSource,
createRef,
forwardRef,
isValidElement,
lazy,
memo,
startTransition,
startTransition as unstable_startTransition, // TODO: Remove once call sights updated to startTransition
unstable_Cache,
unstable_DebugTracingMode,
unstable_LegacyHidden,
unstable_Scope,
unstable_getCacheForType,
unstable_useCacheRefresh,
unstable_useOpaqueIdentifier,
useCallback,
useContext,
useDebugValue,
useDeferredValue,
useDeferredValue as unstable_useDeferredValue, // TODO: Remove once call sights updated to useDeferredValue
useEffect,
useImperativeHandle,
useDebugValue,
useLayoutEffect,
useMemo,
useMutableSource,
useMutableSource as unstable_useMutableSource,
createMutableSource,
createMutableSource as unstable_createMutableSource,
useReducer,
useRef,
useState,
Fragment,
Profiler,
StrictMode,
Suspense,
unstable_LegacyHidden,
createElement,
cloneElement,
isValidElement,
version,
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
// exposeConcurrentModeAPIs
useTransition,
useTransition as unstable_useTransition,
useDeferredValue,
useDeferredValue as unstable_useDeferredValue,
startTransition,
startTransition as unstable_startTransition,
SuspenseList,
SuspenseList as unstable_SuspenseList,
unstable_getCacheForType,
unstable_Cache,
unstable_useCacheRefresh,
// enableScopeAPI
unstable_Scope,
unstable_useOpaqueIdentifier,
// enableDebugTracing
unstable_DebugTracingMode,
useTransition as unstable_useTransition, // TODO: Remove once call sights updated to useTransition
version,
} from './src/React';
export {jsx, jsxs, jsxDEV} from './src/jsx/ReactJSX';

View File

@ -8,32 +8,39 @@
*/
export {
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
Children,
createRef,
Component,
Fragment,
Profiler,
PureComponent,
StrictMode,
Suspense,
SuspenseList,
cloneElement,
createContext,
createElement,
createFactory,
createMutableSource as unstable_createMutableSource,
createRef,
forwardRef,
isValidElement,
lazy,
memo,
startTransition,
unstable_useOpaqueIdentifier,
useCallback,
useContext,
useDebugValue,
useDeferredValue,
useEffect,
useImperativeHandle,
useDebugValue,
useLayoutEffect,
useMemo,
useMutableSource as unstable_useMutableSource,
useReducer,
useRef,
useState,
Fragment,
Profiler,
StrictMode,
Suspense,
createElement,
cloneElement,
isValidElement,
useTransition,
version,
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
createFactory,
} from './src/React';

View File

@ -186,7 +186,6 @@ describe(`onRender`, () => {
expect(callback).toHaveBeenCalledTimes(2);
});
// @gate experimental || !enableSyncDefaultUpdates
it('is not invoked until the commit phase', () => {
const callback = jest.fn();
@ -196,7 +195,7 @@ describe(`onRender`, () => {
};
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactTestRenderer.create(
<React.Profiler id="test" onRender={callback}>
<Yield value="first" />
@ -690,7 +689,6 @@ describe(`onRender`, () => {
expect(onRender.mock.calls[2][1]).toBe('update');
});
// @gate experimental
it('is properly distinguish updates and nested-updates when there is more than sync remaining work', () => {
loadModules({
useNoopRenderer: true,
@ -709,7 +707,7 @@ describe(`onRender`, () => {
const onRender = jest.fn();
// Schedule low-priority work.
React.unstable_startTransition(() =>
React.startTransition(() =>
ReactNoop.render(
<React.Profiler id="root" onRender={onRender}>
<Component />
@ -734,7 +732,6 @@ describe(`onRender`, () => {
});
describe('with regard to interruptions', () => {
// @gate experimental || !enableSyncDefaultUpdates
it('should accumulate actual time after a scheduling interruptions', () => {
const callback = jest.fn();
@ -748,7 +745,7 @@ describe(`onRender`, () => {
// Render partially, but run out of time before completing.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactTestRenderer.create(
<React.Profiler id="test" onRender={callback}>
<Yield renderTime={2} />
@ -781,7 +778,6 @@ describe(`onRender`, () => {
expect(call[5]).toBe(10); // commit time
});
// @gate experimental || !enableSyncDefaultUpdates
it('should not include time between frames', () => {
const callback = jest.fn();
@ -796,7 +792,7 @@ describe(`onRender`, () => {
// Render partially, but don't finish.
// This partial render should take 5ms of simulated time.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
ReactTestRenderer.create(
<React.Profiler id="outer" onRender={callback}>
<Yield renderTime={5} />
@ -847,7 +843,6 @@ describe(`onRender`, () => {
expect(outerCall[5]).toBe(87); // commit time
});
// @gate experimental || !enableSyncDefaultUpdates
it('should report the expected times when a high-pri update replaces a mount in-progress', () => {
const callback = jest.fn();
@ -863,7 +858,7 @@ describe(`onRender`, () => {
// This partial render should take 10ms of simulated time.
let renderer;
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
renderer = ReactTestRenderer.create(
<React.Profiler id="test" onRender={callback}>
<Yield renderTime={10} />
@ -914,7 +909,6 @@ describe(`onRender`, () => {
expect(callback).toHaveBeenCalledTimes(0);
});
// @gate experimental || !enableSyncDefaultUpdates
it('should report the expected times when a high-priority update replaces a low-priority update', () => {
const callback = jest.fn();
@ -951,7 +945,7 @@ describe(`onRender`, () => {
// Render a partially update, but don't finish.
// This partial render should take 3ms of simulated time.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
renderer.update(
<React.Profiler id="test" onRender={callback}>
<Yield renderTime={3} />
@ -1008,7 +1002,6 @@ describe(`onRender`, () => {
expect(callback).toHaveBeenCalledTimes(1);
});
// @gate experimental || !enableSyncDefaultUpdates
it('should report the expected times when a high-priority update interrupts a low-priority update', () => {
const callback = jest.fn();
@ -1076,7 +1069,7 @@ describe(`onRender`, () => {
// Render a partially update, but don't finish.
// This partial render will take 10ms of actual render time.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
first.setState({renderTime: 10});
});
} else {

View File

@ -138,7 +138,6 @@ describe('ReactProfiler DevTools integration', () => {
).toBe(7);
});
// @gate experimental || !enableSyncDefaultUpdates
it('regression test: #17159', () => {
function Text({text}) {
Scheduler.unstable_yieldValue(text);
@ -157,7 +156,7 @@ describe('ReactProfiler DevTools integration', () => {
Scheduler.unstable_advanceTime(10000);
// Schedule an update.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
root.update(<Text text="B" />);
});
} else {

View File

@ -49,7 +49,6 @@ describe('ReactStrictMode', () => {
return null;
}
// @gate experimental
it('should default to not strict', () => {
act(() => {
const container = document.createElement('div');
@ -65,7 +64,6 @@ describe('ReactStrictMode', () => {
});
if (__DEV__) {
// @gate experimental
it('should support enabling strict mode via createRoot option', () => {
act(() => {
const container = document.createElement('div');
@ -87,7 +85,6 @@ describe('ReactStrictMode', () => {
]);
});
// @gate experimental
it('should include legacy + strict effects mode', () => {
act(() => {
const container = document.createElement('div');
@ -111,7 +108,6 @@ describe('ReactStrictMode', () => {
]);
});
// @gate experimental
it('should allow level to be increased with nesting', () => {
act(() => {
const container = document.createElement('div');

View File

@ -362,7 +362,6 @@ describe('Concurrent Mode', () => {
Scheduler = require('scheduler');
});
// @gate experimental
it('should warn about unsafe legacy lifecycle methods anywhere in a StrictMode tree', () => {
function StrictRoot() {
return (
@ -405,7 +404,7 @@ describe('Concurrent Mode', () => {
}
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<StrictRoot />);
expect(() => Scheduler.unstable_flushAll()).toErrorDev(
[
@ -436,7 +435,6 @@ Please update the following components: App`,
Scheduler.unstable_flushAll();
});
// @gate experimental
it('should coalesce warnings by lifecycle name', () => {
function StrictRoot() {
return (
@ -468,7 +466,7 @@ Please update the following components: App`,
}
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<StrictRoot />);
expect(() => {
@ -526,7 +524,6 @@ Please update the following components: Parent`,
Scheduler.unstable_flushAll();
});
// @gate experimental
it('should warn about components not present during the initial render', () => {
function StrictRoot({foo}) {
return <React.StrictMode>{foo ? <Foo /> : <Bar />}</React.StrictMode>;
@ -545,7 +542,7 @@ Please update the following components: Parent`,
}
const container = document.createElement('div');
const root = ReactDOM.unstable_createRoot(container);
const root = ReactDOM.createRoot(container);
root.render(<StrictRoot foo={true} />);
expect(() =>
Scheduler.unstable_flushAll(),

View File

@ -8,31 +8,32 @@
*/
export {
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
Children,
createRef,
forwardRef,
lazy,
memo,
useCallback,
useContext,
useDebugValue,
useMemo,
useMutableSource as unstable_useMutableSource,
createMutableSource as unstable_createMutableSource,
Fragment,
Profiler,
StrictMode,
Suspense,
createElement,
SuspenseList,
cloneElement,
createElement,
createMutableSource as unstable_createMutableSource,
createRef,
forwardRef,
isValidElement,
version,
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
// exposeConcurrentModeAPIs
useDeferredValue as unstable_useDeferredValue,
SuspenseList as unstable_SuspenseList,
unstable_useOpaqueIdentifier,
unstable_getCacheForType,
// enableDebugTracing
lazy,
memo,
startTransition,
unstable_DebugTracingMode,
unstable_getCacheForType,
unstable_useOpaqueIdentifier,
useCallback,
useContext,
useDebugValue,
useDeferredValue,
useDeferredValue as unstable_useDeferredValue,
useMemo,
useMutableSource as unstable_useMutableSource,
useTransition,
version,
} from './src/React';

View File

@ -55,11 +55,11 @@ export const enableProfilerNestedUpdateScheduledHook = false;
export const enableUpdaterTracking = __PROFILE__;
// SSR experiments
export const enableSuspenseServerRenderer = __EXPERIMENTAL__;
export const enableSelectiveHydration = __EXPERIMENTAL__;
export const enableSuspenseServerRenderer = true;
export const enableSelectiveHydration = true;
// Flight experiments
export const enableLazyElements = __EXPERIMENTAL__;
export const enableLazyElements = true;
export const enableCache = __EXPERIMENTAL__;
// Only used in www builds.

View File

@ -23,7 +23,7 @@ export const enableSuspenseLayoutEffectSemantics = __VARIANT__;
// Enable this flag to help with concurrent mode debugging.
// It logs information to the console about React scheduling, rendering, and commit phases.
//
// NOTE: This feature will only work in DEV mode; all callsights are wrapped with __DEV__.
// NOTE: This feature will only work in DEV mode; all callsites are wrapped with __DEV__.
export const enableDebugTracing = __EXPERIMENTAL__;
export const enableUpdaterTracking = false;

View File

@ -262,7 +262,6 @@ describe('useSubscription', () => {
expect(subscriptions).toHaveLength(2);
});
// @gate experimental || !enableSyncDefaultUpdates
it('should ignore values emitted by a new subscribable until the commit phase', () => {
const log = [];
@ -333,7 +332,7 @@ describe('useSubscription', () => {
// Start React update, but don't finish
act(() => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
renderer.update(<Parent observed={observableB} />);
});
} else {
@ -370,7 +369,6 @@ describe('useSubscription', () => {
]);
});
// @gate experimental || !enableSyncDefaultUpdates
it('should not drop values emitted between updates', () => {
const log = [];
@ -442,7 +440,7 @@ describe('useSubscription', () => {
// Start React update, but don't finish
act(() => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
renderer.update(<Parent observed={observableB} />);
});
} else {
@ -576,7 +574,6 @@ describe('useSubscription', () => {
Scheduler.unstable_flushAll();
});
// @gate experimental || !enableSyncDefaultUpdates
it('should not tear if a mutation occurs during a concurrent update', () => {
const input = document.createElement('input');
@ -625,7 +622,7 @@ describe('useSubscription', () => {
// This update will not be eagerly evaluated,
// but useSubscription() should eagerly close over the updated value to avoid tearing.
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
mutate('C');
});
} else {
@ -633,7 +630,7 @@ describe('useSubscription', () => {
}
expect(Scheduler).toFlushAndYieldThrough(['render:first:C']);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.unstable_startTransition(() => {
React.startTransition(() => {
mutate('D');
});
} else {