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:
parent
b8fda6cabc
commit
2bf4805e4b
|
@ -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 {
|
||||
|
|
|
@ -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: [],
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -8,9 +8,11 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
// $FlowFixMe
|
||||
unstable_createMutableSource as createMutableSource,
|
||||
unstable_useMutableSource as useMutableSource,
|
||||
useLayoutEffect,
|
||||
// $FlowFixMe
|
||||
unstable_useMutableSource as useMutableSource,
|
||||
} from 'react';
|
||||
|
||||
import {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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} />));
|
||||
|
|
|
@ -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 />));
|
||||
|
|
|
@ -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} />));
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
import * as React from 'react';
|
||||
import {
|
||||
createContext,
|
||||
unstable_startTransition as startTransition,
|
||||
startTransition,
|
||||
unstable_useCacheRefresh as useCacheRefresh,
|
||||
useCallback,
|
||||
useContext,
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -34,7 +34,7 @@ import {
|
|||
useMemo,
|
||||
useReducer,
|
||||
useRef,
|
||||
unstable_startTransition as startTransition,
|
||||
startTransition,
|
||||
} from 'react';
|
||||
import {createRegExp} from '../utils';
|
||||
import {BridgeContext, StoreContext} from '../context';
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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 />);
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 />);
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
|
||||
|
|
|
@ -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([]);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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} />);
|
||||
});
|
||||
|
|
|
@ -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([]);
|
||||
});
|
||||
|
|
|
@ -1332,7 +1332,7 @@ describe('ReactUpdates', () => {
|
|||
);
|
||||
}
|
||||
|
||||
const root = ReactDOM.unstable_createRoot(container);
|
||||
const root = ReactDOM.createRoot(container);
|
||||
let hiddenDiv;
|
||||
act(() => {
|
||||
root.render(<Foo />);
|
||||
|
|
|
@ -22,7 +22,7 @@ beforeEach(() => {
|
|||
Scheduler = require('scheduler');
|
||||
|
||||
Suspense = React.Suspense;
|
||||
SuspenseList = React.unstable_SuspenseList;
|
||||
SuspenseList = React.SuspenseList;
|
||||
|
||||
getCacheForType = React.unstable_getCacheForType;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -23,6 +23,7 @@ export {
|
|||
Profiler,
|
||||
StrictMode,
|
||||
Suspense,
|
||||
SuspenseList,
|
||||
isAsyncMode,
|
||||
isConcurrentMode,
|
||||
isContextConsumer,
|
||||
|
@ -36,4 +37,5 @@ export {
|
|||
isProfiler,
|
||||
isStrictMode,
|
||||
isSuspense,
|
||||
isSuspenseList,
|
||||
} from './src/ReactIs';
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -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 = [];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(() => {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(() => {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 />);
|
||||
});
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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} />);
|
||||
});
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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('');
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 />
|
||||
|
|
|
@ -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 />);
|
||||
});
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue