this.setState({highPriCount: this.state.highPriCount + 1})
+ // Intentionally not using the updater form here, to test
+ // that updates are serially processed.
+ () => {
+ this.setState({highPriCount: this.state.highPriCount + 1});
+ }
}>
-
-
-
+
);
}
}
// Initial mount
- ReactDOM.render(, container);
+ const root = ReactDOM.unstable_createRoot(container);
+ root.render();
+ expect(Scheduler).toFlushAndYield([
+ 'High-pri count: 0, Low-pri count: 0',
+ ]);
expect(button.textContent).toEqual('High-pri count: 0, Low-pri count: 0');
function click() {
@@ -425,8 +436,12 @@ describe('SimpleEventPlugin', function() {
// Click the button a single time
click();
- // The high-pri counter should flush synchronously, but not the
- // low-pri counter
+ // Nothing should flush on the first click.
+ expect(Scheduler).toHaveYielded([]);
+ // Click again. This will force the previous discrete update to flush. But
+ // only the high-pri count will increase.
+ click();
+ expect(Scheduler).toHaveYielded(['High-pri count: 1, Low-pri count: 0']);
expect(button.textContent).toEqual('High-pri count: 1, Low-pri count: 0');
// Click the button many more times
@@ -437,10 +452,22 @@ describe('SimpleEventPlugin', function() {
click();
click();
- // Flush the remaining work
- Scheduler.flushAll();
- // Both counters should equal the total number of clicks
- expect(button.textContent).toEqual('High-pri count: 7, Low-pri count: 7');
+ // Flush the remaining work.
+ expect(Scheduler).toHaveYielded([
+ 'High-pri count: 2, Low-pri count: 0',
+ 'High-pri count: 3, Low-pri count: 0',
+ 'High-pri count: 4, Low-pri count: 0',
+ 'High-pri count: 5, Low-pri count: 0',
+ 'High-pri count: 6, Low-pri count: 0',
+ 'High-pri count: 7, Low-pri count: 0',
+ ]);
+
+ // At the end, both counters should equal the total number of clicks
+ expect(Scheduler).toFlushAndYield([
+ 'High-pri count: 8, Low-pri count: 0',
+ 'High-pri count: 8, Low-pri count: 8',
+ ]);
+ expect(button.textContent).toEqual('High-pri count: 8, Low-pri count: 8');
});
});
diff --git a/packages/react-is/README.md b/packages/react-is/README.md
index f01acef953511..9adeee1d9aad1 100644
--- a/packages/react-is/README.md
+++ b/packages/react-is/README.md
@@ -45,16 +45,6 @@ ReactIs.isValidElementType(React.createFactory("div")); // true
### Determining an Element's Type
-#### ConcurrentMode
-
-```js
-import React from "react";
-import * as ReactIs from 'react-is';
-
-ReactIs.isConcurrentMode(); // true
-ReactIs.typeOf() === ReactIs.ConcurrentMode; // true
-```
-
#### Context
```js
diff --git a/packages/react-is/src/__tests__/ReactIs-test.js b/packages/react-is/src/__tests__/ReactIs-test.js
index 4889d0f74f313..1c47fd551bb58 100644
--- a/packages/react-is/src/__tests__/ReactIs-test.js
+++ b/packages/react-is/src/__tests__/ReactIs-test.js
@@ -58,9 +58,6 @@ describe('ReactIs', () => {
true,
);
expect(ReactIs.isValidElementType(React.Fragment)).toEqual(true);
- expect(ReactIs.isValidElementType(React.unstable_ConcurrentMode)).toEqual(
- true,
- );
expect(ReactIs.isValidElementType(React.StrictMode)).toEqual(true);
expect(ReactIs.isValidElementType(React.Suspense)).toEqual(true);
@@ -72,20 +69,6 @@ describe('ReactIs', () => {
expect(ReactIs.isValidElementType({type: 'div', props: {}})).toEqual(false);
});
- it('should identify concurrent mode', () => {
- expect(ReactIs.typeOf()).toBe(
- ReactIs.ConcurrentMode,
- );
- expect(ReactIs.isConcurrentMode()).toBe(
- true,
- );
- expect(ReactIs.isConcurrentMode({type: ReactIs.ConcurrentMode})).toBe(
- false,
- );
- expect(ReactIs.isConcurrentMode()).toBe(false);
- expect(ReactIs.isConcurrentMode()).toBe(false);
- });
-
it('should identify context consumers', () => {
const Context = React.createContext(false);
expect(ReactIs.typeOf()).toBe(ReactIs.ContextConsumer);
@@ -117,7 +100,6 @@ describe('ReactIs', () => {
expect(ReactIs.isElement()).toBe(true);
expect(ReactIs.isElement()).toBe(true);
expect(ReactIs.isElement()).toBe(true);
- expect(ReactIs.isElement()).toBe(true);
expect(ReactIs.isElement()).toBe(true);
expect(ReactIs.isElement()).toBe(true);
});
@@ -127,7 +109,6 @@ describe('ReactIs', () => {
expect(ReactIs.typeOf()).toBe(ReactIs.ForwardRef);
expect(ReactIs.isForwardRef()).toBe(true);
expect(ReactIs.isForwardRef({type: ReactIs.StrictMode})).toBe(false);
- expect(ReactIs.isForwardRef()).toBe(false);
expect(ReactIs.isForwardRef()).toBe(false);
});
@@ -168,7 +149,6 @@ describe('ReactIs', () => {
expect(ReactIs.typeOf()).toBe(ReactIs.StrictMode);
expect(ReactIs.isStrictMode()).toBe(true);
expect(ReactIs.isStrictMode({type: ReactIs.StrictMode})).toBe(false);
- expect(ReactIs.isStrictMode()).toBe(false);
expect(ReactIs.isStrictMode()).toBe(false);
});
@@ -188,7 +168,6 @@ describe('ReactIs', () => {
ReactIs.isProfiler(),
).toBe(true);
expect(ReactIs.isProfiler({type: ReactIs.Profiler})).toBe(false);
- expect(ReactIs.isProfiler()).toBe(false);
expect(ReactIs.isProfiler()).toBe(false);
});
});
diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js
index 2080cbc17a23b..282ab0a0787fd 100644
--- a/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactIncrementalPerf-test.internal.js
@@ -189,14 +189,12 @@ describe('ReactDebugFiberPerf', () => {
expect(getFlameChart()).toMatchSnapshot();
});
- it('does not include ConcurrentMode, StrictMode, or Profiler components in measurements', () => {
+ it('does not include StrictMode or Profiler components in measurements', () => {
ReactNoop.render(
-
-
-
+ ,
diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.internal.js b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.internal.js
index ee45396a4d173..b74488faeaf0d 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.internal.js
@@ -5,8 +5,6 @@ let ReactNoop;
let Scheduler;
let ReactCache;
let Suspense;
-let StrictMode;
-let ConcurrentMode;
let TextResource;
let textResourceShouldFail;
@@ -26,8 +24,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
Scheduler = require('scheduler');
ReactCache = require('react-cache');
Suspense = React.Suspense;
- StrictMode = React.StrictMode;
- ConcurrentMode = React.unstable_ConcurrentMode;
TextResource = ReactCache.unstable_createResource(([text, ms = 0]) => {
return new Promise((resolve, reject) =>
@@ -896,7 +892,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(ReactNoop.getChildren()).toEqual([span('Result')]);
});
- it('times out immediately when Suspense is in loose mode, even if the suspender is async', async () => {
+ it('times out immediately when Suspense is in legacy mode', async () => {
class UpdatingText extends React.Component {
state = {step: 1};
render() {
@@ -918,15 +914,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
function App() {
return (
}>
-
-
-
-
+
+
);
}
- // Initial mount. This is synchronous, because the root is sync.
+ // Initial mount.
ReactNoop.renderLegacySyncRoot();
await advanceTimers(100);
expect(Scheduler).toHaveYielded([
@@ -945,14 +939,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
,
);
- // Update. This starts out asynchronously.
+ // Update.
text.current.setState({step: 2}, () =>
Scheduler.yieldValue('Update did commit'),
);
- // Suspend during an async render.
- expect(ReactNoop.flushNextYield()).toEqual(['Suspend! [Step: 2]']);
- expect(Scheduler).toFlushAndYield([
+ expect(ReactNoop.flushNextYield()).toEqual([
+ 'Suspend! [Step: 2]',
'Loading (1)',
'Loading (2)',
'Loading (3)',
@@ -979,269 +972,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
);
});
- it(
- 'continues rendering asynchronously even if a promise is captured by ' +
- 'a sync boundary (legacy mode)',
- async () => {
- class UpdatingText extends React.Component {
- state = {text: this.props.initialText};
- render() {
- return this.props.children(this.state.text);
- }
- }
-
- const text1 = React.createRef(null);
- const text2 = React.createRef(null);
- function App() {
- return (
-
- }>
-
-
- {text => (
-
-
-
-
-
- )}
-
-
-
-
-
- {text => (
-
-
-
-
-
- )}
-
-
-
- );
- }
-
- // Initial mount
- ReactNoop.renderLegacySyncRoot(, () =>
- Scheduler.yieldValue('Did mount'),
- );
- await advanceTimers(100);
-
- expect(Scheduler).toHaveYielded([
- 'Before',
- 'Suspend! [Async: 1]',
- 'After',
- 'Loading...',
- 'Before',
- 'Sync: 1',
- 'After',
- 'Did mount',
- 'Promise resolved [Async: 1]',
- ]);
- expect(Scheduler).toFlushExpired(['Async: 1']);
- expect(ReactNoop).toMatchRenderedOutput(
-
-
-
-
-
-
-
-
- ,
- );
-
- // Update. This starts out asynchronously.
- text1.current.setState({text: 'Async: 2'}, () =>
- Scheduler.yieldValue('Update 1 did commit'),
- );
- text2.current.setState({text: 'Sync: 2'}, () =>
- Scheduler.yieldValue('Update 2 did commit'),
- );
-
- // Start rendering asynchronously
- expect(Scheduler).toFlushAndYieldThrough(['Before']);
-
- // Now render the next child, which suspends
- expect(ReactNoop.flushNextYield()).toEqual([
- // This child suspends
- 'Suspend! [Async: 2]',
- ]);
- expect(Scheduler).toFlushAndYield([
- 'After',
- 'Loading...',
- 'Before',
- 'Sync: 2',
- 'After',
- 'Update 1 did commit',
- 'Update 2 did commit',
- ]);
- expect(ReactNoop).toMatchRenderedOutput(
-
-
-
-
-
-
-
-
-
- ,
- );
-
- // When the placeholder is pinged, the boundary must be re-rendered
- // synchronously.
- await advanceTimers(100);
-
- expect(Scheduler).toHaveYielded(['Promise resolved [Async: 2]']);
- expect(Scheduler).toFlushExpired(['Async: 2']);
- expect(ReactNoop).toMatchRenderedOutput(
-
-
-
-
-
-
-
-
- ,
- );
- },
- );
-
- it(
- 'continues rendering asynchronously even if a promise is captured by ' +
- 'a sync boundary (strict, legacy)',
- async () => {
- class UpdatingText extends React.Component {
- state = {text: this.props.initialText};
- render() {
- return this.props.children(this.state.text);
- }
- }
-
- const text1 = React.createRef(null);
- const text2 = React.createRef(null);
- function App() {
- return (
-
- }>
-
-
- {text => (
-
-
-
-
-
- )}
-
-
-
-
-
- {text => (
-
-
-
-
-
- )}
-
-
-
- );
- }
-
- // Initial mount
- ReactNoop.renderLegacySyncRoot(, () =>
- Scheduler.yieldValue('Did mount'),
- );
- await advanceTimers(100);
- expect(Scheduler).toHaveYielded([
- 'Before',
- 'Suspend! [Async: 1]',
- 'After',
- 'Loading...',
- 'Before',
- 'Sync: 1',
- 'After',
- 'Did mount',
- 'Promise resolved [Async: 1]',
- ]);
- expect(Scheduler).toFlushExpired(['Async: 1']);
- expect(ReactNoop).toMatchRenderedOutput(
-
-
-
-
-
-
-
-
- ,
- );
-
- // Update. This starts out asynchronously.
- text1.current.setState({text: 'Async: 2'}, () =>
- Scheduler.yieldValue('Update 1 did commit'),
- );
- text2.current.setState({text: 'Sync: 2'}, () =>
- Scheduler.yieldValue('Update 2 did commit'),
- );
-
- // Start rendering asynchronously
- expect(Scheduler).toFlushAndYieldThrough(['Before']);
-
- // Now render the next child, which suspends
- expect(ReactNoop.flushNextYield()).toEqual([
- // This child suspends
- 'Suspend! [Async: 2]',
- ]);
- expect(Scheduler).toFlushAndYield([
- 'After',
- 'Loading...',
- 'Before',
- 'Sync: 2',
- 'After',
- 'Update 1 did commit',
- 'Update 2 did commit',
- ]);
- expect(ReactNoop).toMatchRenderedOutput(
-
-
-
-
-
-
-
-
-
- ,
- );
-
- // When the placeholder is pinged, the boundary must be re-rendered
- // synchronously.
- await advanceTimers(100);
-
- expect(Scheduler).toHaveYielded(['Promise resolved [Async: 2]']);
- expect(Scheduler).toFlushExpired(['Async: 2']);
- expect(ReactNoop).toMatchRenderedOutput(
-
-
-
-
-
-
-
-
- ,
- );
- },
- );
-
it('does not re-render siblings in loose mode', async () => {
class TextWithLifecycle extends React.Component {
componentDidMount() {
diff --git a/packages/react-reconciler/src/__tests__/__snapshots__/ReactIncrementalPerf-test.internal.js.snap b/packages/react-reconciler/src/__tests__/__snapshots__/ReactIncrementalPerf-test.internal.js.snap
index b9845de602cb7..4372eb2baca1f 100644
--- a/packages/react-reconciler/src/__tests__/__snapshots__/ReactIncrementalPerf-test.internal.js.snap
+++ b/packages/react-reconciler/src/__tests__/__snapshots__/ReactIncrementalPerf-test.internal.js.snap
@@ -91,7 +91,7 @@ exports[`ReactDebugFiberPerf deduplicates lifecycle names during commit to reduc
"
`;
-exports[`ReactDebugFiberPerf does not include ConcurrentMode, StrictMode, or Profiler components in measurements 1`] = `
+exports[`ReactDebugFiberPerf does not include StrictMode or Profiler components in measurements 1`] = `
"⚛ (Waiting for async callback...)
// Mount
diff --git a/packages/react/src/React.js b/packages/react/src/React.js
index a5a0411fd0364..8c7ee01d45d9d 100644
--- a/packages/react/src/React.js
+++ b/packages/react/src/React.js
@@ -7,7 +7,6 @@
import ReactVersion from 'shared/ReactVersion';
import {
- REACT_CONCURRENT_MODE_TYPE,
REACT_FRAGMENT_TYPE,
REACT_PROFILER_TYPE,
REACT_STRICT_MODE_TYPE,
@@ -51,12 +50,7 @@ import {
} from './ReactElementValidator';
import ReactSharedInternals from './ReactSharedInternals';
import {error, warn} from './withComponentStack';
-import {
- enableEventAPI,
- enableStableConcurrentModeAPIs,
- enableJSXTransformAPI,
-} from 'shared/ReactFeatureFlags';
-
+import {enableEventAPI, enableJSXTransformAPI} from 'shared/ReactFeatureFlags';
const React = {
Children: {
map,
@@ -101,8 +95,6 @@ const React = {
version: ReactVersion,
- unstable_ConcurrentMode: REACT_CONCURRENT_MODE_TYPE,
-
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: ReactSharedInternals,
};
@@ -115,11 +107,6 @@ if (enableEventAPI) {
React.unstable_createEventComponent = createEventComponent;
}
-if (enableStableConcurrentModeAPIs) {
- React.ConcurrentMode = REACT_CONCURRENT_MODE_TYPE;
- React.unstable_ConcurrentMode = undefined;
-}
-
if (enableJSXTransformAPI) {
if (__DEV__) {
React.jsxDEV = jsxWithValidation;
diff --git a/packages/react/src/__tests__/ReactStrictMode-test.internal.js b/packages/react/src/__tests__/ReactStrictMode-test.internal.js
index 14b33ce991805..c674a5b03e18e 100644
--- a/packages/react/src/__tests__/ReactStrictMode-test.internal.js
+++ b/packages/react/src/__tests__/ReactStrictMode-test.internal.js
@@ -10,6 +10,7 @@
'use strict';
let React;
+let Scheduler;
let ReactFeatureFlags;
let ReactTestRenderer;
let PropTypes;
@@ -21,6 +22,7 @@ describe('ReactStrictMode', () => {
ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.debugRenderPhaseSideEffects = true;
React = require('react');
+ Scheduler = require('scheduler');
ReactTestRenderer = require('react-test-renderer');
});
@@ -153,6 +155,7 @@ describe('ReactStrictMode', () => {
ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = debugRenderPhaseSideEffectsForStrictMode;
React = require('react');
+ Scheduler = require('scheduler');
ReactTestRenderer = require('react-test-renderer');
});
@@ -298,27 +301,16 @@ describe('ReactStrictMode', () => {
});
});
- describe('async subtree', () => {
+ describe('Concurrent Mode', () => {
beforeEach(() => {
jest.resetModules();
React = require('react');
+ Scheduler = require('scheduler');
ReactTestRenderer = require('react-test-renderer');
});
- it('should warn about unsafe legacy lifecycle methods within the tree', () => {
- class SyncRoot extends React.Component {
- UNSAFE_componentWillMount() {}
- UNSAFE_componentWillUpdate() {}
- UNSAFE_componentWillReceiveProps() {}
- render() {
- return (
-
-
-
- );
- }
- }
+ it('should warn about unsafe legacy lifecycle methods anywhere in the tree', () => {
class AsyncRoot extends React.Component {
UNSAFE_componentWillMount() {}
UNSAFE_componentWillUpdate() {}
@@ -352,13 +344,12 @@ describe('ReactStrictMode', () => {
}
}
- let rendered;
- expect(() => {
- rendered = ReactTestRenderer.create();
- }).toWarnDev(
+ const root = ReactTestRenderer.create(null, {
+ unstable_isConcurrent: true,
+ });
+ root.update();
+ expect(() => Scheduler.flushAll()).toWarnDev(
'Unsafe lifecycle methods were found within a strict-mode tree:' +
- '\n in ConcurrentMode (at **)' +
- '\n in SyncRoot (at **)' +
'\n\ncomponentWillMount: Please update the following components ' +
'to use componentDidMount instead: AsyncRoot' +
'\n\ncomponentWillReceiveProps: Please update the following components ' +
@@ -367,26 +358,15 @@ describe('ReactStrictMode', () => {
'to use componentDidUpdate instead: AsyncRoot' +
'\n\nLearn more about this warning here:' +
'\nhttps://fb.me/react-strict-mode-warnings',
+ {withoutStack: true},
);
// Dedupe
- rendered = ReactTestRenderer.create();
- rendered.update();
+ root.update();
+ Scheduler.flushAll();
});
it('should coalesce warnings by lifecycle name', () => {
- class SyncRoot extends React.Component {
- UNSAFE_componentWillMount() {}
- UNSAFE_componentWillUpdate() {}
- UNSAFE_componentWillReceiveProps() {}
- render() {
- return (
-
-
-
- );
- }
- }
class AsyncRoot extends React.Component {
UNSAFE_componentWillMount() {}
UNSAFE_componentWillUpdate() {}
@@ -409,15 +389,14 @@ describe('ReactStrictMode', () => {
}
}
- let rendered;
+ const root = ReactTestRenderer.create(null, {
+ unstable_isConcurrent: true,
+ });
+ root.update();
expect(() => {
- expect(
- () => (rendered = ReactTestRenderer.create()),
- ).toWarnDev(
+ expect(() => Scheduler.flushAll()).toWarnDev(
'Unsafe lifecycle methods were found within a strict-mode tree:' +
- '\n in ConcurrentMode (at **)' +
- '\n in SyncRoot (at **)' +
'\n\ncomponentWillMount: Please update the following components ' +
'to use componentDidMount instead: AsyncRoot, Parent' +
'\n\ncomponentWillReceiveProps: Please update the following components ' +
@@ -426,6 +405,7 @@ describe('ReactStrictMode', () => {
'to use componentDidUpdate instead: AsyncRoot, Parent' +
'\n\nLearn more about this warning here:' +
'\nhttps://fb.me/react-strict-mode-warnings',
+ {withoutStack: true},
);
}).toLowPriorityWarnDev(
[
@@ -437,103 +417,14 @@ describe('ReactStrictMode', () => {
);
// Dedupe
- rendered = ReactTestRenderer.create();
- rendered.update();
- });
-
- it('should group warnings by async root', () => {
- class SyncRoot extends React.Component {
- UNSAFE_componentWillMount() {}
- UNSAFE_componentWillUpdate() {}
- UNSAFE_componentWillReceiveProps() {}
- render() {
- return (
-
-
-
-
- );
- }
- }
- class AsyncRootOne extends React.Component {
- render() {
- return (
-
-
-
-
-
- );
- }
- }
- class AsyncRootTwo extends React.Component {
- render() {
- return (
-
-
-
-
-
- );
- }
- }
- class Foo extends React.Component {
- componentWillMount() {}
- render() {
- return this.props.children;
- }
- }
- class Bar extends React.Component {
- componentWillMount() {}
- render() {
- return null;
- }
- }
- class Baz extends React.Component {
- componentWillMount() {}
- render() {
- return null;
- }
- }
-
- let rendered;
-
- expect(() => {
- expect(
- () => (rendered = ReactTestRenderer.create()),
- ).toWarnDev([
- 'Unsafe lifecycle methods were found within a strict-mode tree:' +
- '\n in ConcurrentMode (at **)' +
- '\n in AsyncRootOne (at **)' +
- '\n in div (at **)' +
- '\n in SyncRoot (at **)' +
- '\n\ncomponentWillMount: Please update the following components ' +
- 'to use componentDidMount instead: Bar, Foo',
- 'Unsafe lifecycle methods were found within a strict-mode tree:' +
- '\n in ConcurrentMode (at **)' +
- '\n in AsyncRootTwo (at **)' +
- '\n in div (at **)' +
- '\n in SyncRoot (at **)' +
- '\n\ncomponentWillMount: Please update the following components ' +
- 'to use componentDidMount instead: Baz',
- ]);
- }).toLowPriorityWarnDev(['componentWillMount is deprecated'], {
- withoutStack: true,
- });
-
- // Dedupe
- rendered = ReactTestRenderer.create();
- rendered.update();
+ root.update();
+ Scheduler.flushAll();
});
it('should warn about components not present during the initial render', () => {
class AsyncRoot extends React.Component {
render() {
- return (
-
- {this.props.foo ? : }
-
- );
+ return this.props.foo ? : ;
}
}
class Foo extends React.Component {
@@ -549,32 +440,34 @@ describe('ReactStrictMode', () => {
}
}
- let rendered;
- expect(() => {
- rendered = ReactTestRenderer.create();
- }).toWarnDev(
+ const root = ReactTestRenderer.create(null, {
+ unstable_isConcurrent: true,
+ });
+ root.update();
+ expect(() => Scheduler.flushAll()).toWarnDev(
'Unsafe lifecycle methods were found within a strict-mode tree:' +
- '\n in ConcurrentMode (at **)' +
- '\n in AsyncRoot (at **)' +
'\n\ncomponentWillMount: Please update the following components ' +
'to use componentDidMount instead: Foo' +
'\n\nLearn more about this warning here:' +
'\nhttps://fb.me/react-strict-mode-warnings',
+ {withoutStack: true},
);
- expect(() => rendered.update()).toWarnDev(
+ root.update();
+ expect(() => Scheduler.flushAll()).toWarnDev(
'Unsafe lifecycle methods were found within a strict-mode tree:' +
- '\n in ConcurrentMode (at **)' +
- '\n in AsyncRoot (at **)' +
'\n\ncomponentWillMount: Please update the following components ' +
'to use componentDidMount instead: Bar' +
'\n\nLearn more about this warning here:' +
'\nhttps://fb.me/react-strict-mode-warnings',
+ {withoutStack: true},
);
// Dedupe
- rendered.update();
- rendered.update();
+ root.update();
+ Scheduler.flushAll();
+ root.update();
+ Scheduler.flushAll();
});
it('should also warn inside of "strict" mode trees', () => {
diff --git a/packages/shared/ReactSymbols.js b/packages/shared/ReactSymbols.js
index cde9f89c5b463..cecaaaf7d019e 100644
--- a/packages/shared/ReactSymbols.js
+++ b/packages/shared/ReactSymbols.js
@@ -32,6 +32,8 @@ export const REACT_PROVIDER_TYPE = hasSymbol
export const REACT_CONTEXT_TYPE = hasSymbol
? Symbol.for('react.context')
: 0xeace;
+// TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
+// (unstable) APIs that have been removed. Can we remove the symbols?
export const REACT_ASYNC_MODE_TYPE = hasSymbol
? Symbol.for('react.async_mode')
: 0xeacf;
diff --git a/packages/shared/getComponentName.js b/packages/shared/getComponentName.js
index 32f174e2b4e6b..6e7c021227730 100644
--- a/packages/shared/getComponentName.js
+++ b/packages/shared/getComponentName.js
@@ -11,7 +11,6 @@ import type {LazyComponent} from 'shared/ReactLazyComponent';
import warningWithoutStack from 'shared/warningWithoutStack';
import {
- REACT_CONCURRENT_MODE_TYPE,
REACT_CONTEXT_TYPE,
REACT_FORWARD_REF_TYPE,
REACT_FRAGMENT_TYPE,
@@ -64,8 +63,6 @@ function getComponentName(type: mixed): string | null {
return type;
}
switch (type) {
- case REACT_CONCURRENT_MODE_TYPE:
- return 'ConcurrentMode';
case REACT_FRAGMENT_TYPE:
return 'Fragment';
case REACT_PORTAL_TYPE: