@samitouri / QOS-React / commits / 8af6728c6f

Enable Suspense + rename Placeholder (#13799)

* Enable Suspense * <unstable_Placeholder delayMs> => <unstable_Suspense maxDuration> * Update suspense fixture

Dan Abramov committed Oct 10, 2018 at 17:02 UTC 8af6728c6f105d37f9c0006288a6d1ac3903dc71
30 files changed +326 -362
fixtures/unstable-async/suspense/README.md
+2 -8
@@ -14,19 +14,13 @@ No. The APIs being tested here are unstable and some of them have still not been
14
15 Clone the React repository.
16
17 -First, open this file locally:
18 -
19 -* `packages/shared/ReactFeatureFlags.js` (make sure you didn't open a similarly named file!)
20 -
21 -Set [the `enableSuspense` flag](https://github.com/facebook/react/blob/d79238f1eeb6634ba7a3df23c3b2709b56cbb8b2/packages/shared/ReactFeatureFlags.js#L19) to `true` and save the file.
22 -
23 -**After you've done that,** follow these steps:
17 +Follow these steps:
18
19 ```shell
20 # 1: Build react from source
21 cd /path/to/react
22 yarn
29 -yarn build dom-client,core,react-cache,schedule --type=NODE
23 +yarn build dom-client,core,react-cache,scheduler --type=NODE
24
25 # 2: Install fixture dependencies
26 cd fixtures/unstable-async/suspense/
fixtures/unstable-async/suspense/src/components/App.js
+5 -5
@@ -1,4 +1,4 @@
1 -import React, {Placeholder, PureComponent} from 'react';
1 +import React, {unstable_Suspense as Suspense, PureComponent} from 'react';
2 import {unstable_scheduleCallback} from 'scheduler';
3 import {
4 unstable_trace as trace,
@@ -76,21 +76,21 @@ export default class App extends PureComponent {
76 }}>
77 Return to list
78 </button>
79 - <Placeholder delayMs={2000} fallback={<Spinner size="large" />}>
79 + <Suspense maxDuration={2000} fallback={<Spinner size="large" />}>
80 <UserPageLoader id={id} />
81 - </Placeholder>
81 + </Suspense>
82 </div>
83 );
84 }
85
86 renderList(loadingId) {
87 return (
88 - <Placeholder delayMs={1500} fallback={<Spinner size="large" />}>
88 + <Suspense maxDuration={1500} fallback={<Spinner size="large" />}>
89 <ContributorListPage
90 loadingId={loadingId}
91 onUserClick={this.handleUserClick}
92 />
93 - </Placeholder>
93 + </Suspense>
94 );
95 }
96 }
fixtures/unstable-async/suspense/src/components/UserPage.js
+5 -5
@@ -1,4 +1,4 @@
1 -import React, {Placeholder} from 'react';
1 +import React, {unstable_Suspense as Suspense} from 'react';
2 import {createResource} from 'react-cache';
3 import Spinner from './Spinner';
4 import {cache} from '../cache';
@@ -14,9 +14,9 @@ export default function UserPage({id}) {
14 alignItems: 'start',
15 }}>
16 <UserDetails id={id} />
17 - <Placeholder delayMs={1000} fallback={<Spinner size="medium" />}>
17 + <Suspense maxDuration={1000} fallback={<Spinner size="medium" />}>
18 <Repositories id={id} />
19 - </Placeholder>
19 + </Suspense>
20 </div>
21 );
22 }
@@ -118,7 +118,7 @@ function Img({src, alt, ...rest}) {
118
119 function UserPicture({source}) {
120 return (
121 - <Placeholder delayMs={1500} fallback={<img src={source} alt="poster" />}>
121 + <Suspense maxDuration={1500} fallback={<img src={source} alt="poster" />}>
122 <Img
123 src={source}
124 alt="profile picture"
@@ -128,7 +128,7 @@ function UserPicture({source}) {
128 borderRadius: '0.5rem',
129 }}
130 />
131 - </Placeholder>
131 + </Suspense>
132 );
133 }
134
packages/react-dom/src/__tests__/ReactDOMServerSuspense-test.internal.js renamed
+3 -4
@@ -21,7 +21,6 @@ function initModules() {
21 jest.resetModuleRegistry();
22
23 ReactFeatureFlags = require('shared/ReactFeatureFlags');
24 - ReactFeatureFlags.enableSuspense = true;
24 ReactFeatureFlags.enableSuspenseServerRenderer = true;
25
26 React = require('react');
@@ -39,7 +38,7 @@ const {resetModules, serverRender} = ReactDOMServerIntegrationUtils(
38 initModules,
39 );
40
42 -describe('ReactDOMServerPlaceholders', () => {
41 +describe('ReactDOMServerSuspense', () => {
42 beforeEach(() => {
43 resetModules();
44 });
@@ -49,9 +48,9 @@ describe('ReactDOMServerPlaceholders', () => {
48 throw new Promise(() => {});
49 };
50 const e = await serverRender(
52 - <React.Placeholder fallback={<div />}>
51 + <React.unstable_Suspense fallback={<div />}>
52 <Suspended />
54 - </React.Placeholder>,
53 + </React.unstable_Suspense>,
54 );
55
56 expect(e.tagName).toBe('DIV');
packages/react-dom/src/server/ReactPartialRenderer.js
+2 -2
@@ -33,7 +33,7 @@ import {
33 REACT_FRAGMENT_TYPE,
34 REACT_STRICT_MODE_TYPE,
35 REACT_CONCURRENT_MODE_TYPE,
36 - REACT_PLACEHOLDER_TYPE,
36 + REACT_SUSPENSE_TYPE,
37 REACT_PORTAL_TYPE,
38 REACT_PROFILER_TYPE,
39 REACT_PROVIDER_TYPE,
@@ -916,7 +916,7 @@ class ReactDOMServerRenderer {
916 this.stack.push(frame);
917 return '';
918 }
919 - case REACT_PLACEHOLDER_TYPE: {
919 + case REACT_SUSPENSE_TYPE: {
920 if (enableSuspenseServerRenderer) {
921 const nextChildren = toArray(
922 // Always use the fallback when synchronously rendering to string.
packages/react-reconciler/src/ReactFiber.js
+4 -4
@@ -33,7 +33,7 @@ import {
33 ContextProvider,
34 ContextConsumer,
35 Profiler,
36 - PlaceholderComponent,
36 + SuspenseComponent,
37 FunctionComponentLazy,
38 ClassComponentLazy,
39 ForwardRefLazy,
@@ -58,7 +58,7 @@ import {
58 REACT_PROVIDER_TYPE,
59 REACT_CONTEXT_TYPE,
60 REACT_CONCURRENT_MODE_TYPE,
61 - REACT_PLACEHOLDER_TYPE,
61 + REACT_SUSPENSE_TYPE,
62 REACT_PURE_TYPE,
63 } from 'shared/ReactSymbols';
64
@@ -442,8 +442,8 @@ export function createFiberFromElement(
442 break;
443 case REACT_PROFILER_TYPE:
444 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
445 - case REACT_PLACEHOLDER_TYPE:
446 - fiberTag = PlaceholderComponent;
445 + case REACT_SUSPENSE_TYPE:
446 + fiberTag = SuspenseComponent;
447 break;
448 default: {
449 if (typeof type === 'object' && type !== null) {
packages/react-reconciler/src/ReactFiberBeginWork.js
+58 -64
@@ -30,7 +30,7 @@ import {
30 ContextProvider,
31 ContextConsumer,
32 Profiler,
33 - PlaceholderComponent,
33 + SuspenseComponent,
34 PureComponent,
35 PureComponentLazy,
36 } from 'shared/ReactWorkTags';
@@ -45,7 +45,6 @@ import {
45 } from 'shared/ReactSideEffectTags';
46 import ReactSharedInternals from 'shared/ReactSharedInternals';
47 import {
48 - enableSuspense,
48 debugRenderPhaseSideEffects,
49 debugRenderPhaseSideEffectsForStrictMode,
50 enableProfilerTimer,
@@ -935,77 +934,72 @@ function mountIndeterminateComponent(
934 }
935 }
936
938 -function updatePlaceholderComponent(
937 +function updateSuspenseComponent(
938 current,
939 workInProgress,
940 renderExpirationTime,
941 ) {
943 - if (enableSuspense) {
944 - const nextProps = workInProgress.pendingProps;
945 -
946 - // Check if we already attempted to render the normal state. If we did,
947 - // and we timed out, render the placeholder state.
948 - const alreadyCaptured =
949 - (workInProgress.effectTag & DidCapture) === NoEffect;
950 -
951 - let nextDidTimeout;
952 - if (current !== null && workInProgress.updateQueue !== null) {
953 - // We're outside strict mode. Something inside this Placeholder boundary
954 - // suspended during the last commit. Switch to the placholder.
955 - workInProgress.updateQueue = null;
956 - nextDidTimeout = true;
957 - } else {
958 - nextDidTimeout = !alreadyCaptured;
959 - }
942 + const nextProps = workInProgress.pendingProps;
943
961 - if ((workInProgress.mode & StrictMode) !== NoEffect) {
962 - if (nextDidTimeout) {
963 - // If the timed-out view commits, schedule an update effect to record
964 - // the committed time.
965 - workInProgress.effectTag |= Update;
966 - } else {
967 - // The state node points to the time at which placeholder timed out.
968 - // We can clear it once we switch back to the normal children.
969 - workInProgress.stateNode = null;
970 - }
971 - }
944 + // Check if we already attempted to render the normal state. If we did,
945 + // and we timed out, render the placeholder state.
946 + const alreadyCaptured = (workInProgress.effectTag & DidCapture) === NoEffect;
947
973 - // If the `children` prop is a function, treat it like a render prop.
974 - // TODO: This is temporary until we finalize a lower level API.
975 - const children = nextProps.children;
976 - let nextChildren;
977 - if (typeof children === 'function') {
978 - nextChildren = children(nextDidTimeout);
979 - } else {
980 - nextChildren = nextDidTimeout ? nextProps.fallback : children;
981 - }
948 + let nextDidTimeout;
949 + if (current !== null && workInProgress.updateQueue !== null) {
950 + // We're outside strict mode. Something inside this Placeholder boundary
951 + // suspended during the last commit. Switch to the placholder.
952 + workInProgress.updateQueue = null;
953 + nextDidTimeout = true;
954 + } else {
955 + nextDidTimeout = !alreadyCaptured;
956 + }
957
983 - if (current !== null && nextDidTimeout !== workInProgress.memoizedState) {
984 - // We're about to switch from the placeholder children to the normal
985 - // children, or vice versa. These are two different conceptual sets that
986 - // happen to be stored in the same set. Call this special function to
987 - // force the new set not to match with the current set.
988 - // TODO: The proper way to model this is by storing each set separately.
989 - forceUnmountCurrentAndReconcile(
990 - current,
991 - workInProgress,
992 - nextChildren,
993 - renderExpirationTime,
994 - );
958 + if ((workInProgress.mode & StrictMode) !== NoEffect) {
959 + if (nextDidTimeout) {
960 + // If the timed-out view commits, schedule an update effect to record
961 + // the committed time.
962 + workInProgress.effectTag |= Update;
963 } else {
996 - reconcileChildren(
997 - current,
998 - workInProgress,
999 - nextChildren,
1000 - renderExpirationTime,
1001 - );
964 + // The state node points to the time at which placeholder timed out.
965 + // We can clear it once we switch back to the normal children.
966 + workInProgress.stateNode = null;
967 }
1003 - workInProgress.memoizedProps = nextProps;
1004 - workInProgress.memoizedState = nextDidTimeout;
1005 - return workInProgress.child;
968 + }
969 +
970 + // If the `children` prop is a function, treat it like a render prop.
971 + // TODO: This is temporary until we finalize a lower level API.
972 + const children = nextProps.children;
973 + let nextChildren;
974 + if (typeof children === 'function') {
975 + nextChildren = children(nextDidTimeout);
976 } else {
1007 - return null;
977 + nextChildren = nextDidTimeout ? nextProps.fallback : children;
978 + }
979 +
980 + if (current !== null && nextDidTimeout !== workInProgress.memoizedState) {
981 + // We're about to switch from the placeholder children to the normal
982 + // children, or vice versa. These are two different conceptual sets that
983 + // happen to be stored in the same set. Call this special function to
984 + // force the new set not to match with the current set.
985 + // TODO: The proper way to model this is by storing each set separately.
986 + forceUnmountCurrentAndReconcile(
987 + current,
988 + workInProgress,
989 + nextChildren,
990 + renderExpirationTime,
991 + );
992 + } else {
993 + reconcileChildren(
994 + current,
995 + workInProgress,
996 + nextChildren,
997 + renderExpirationTime,
998 + );
999 }
1000 + workInProgress.memoizedProps = nextProps;
1001 + workInProgress.memoizedState = nextDidTimeout;
1002 + return workInProgress.child;
1003 }
1004
1005 function updatePortalComponent(
@@ -1342,8 +1336,8 @@ function beginWork(
1336 return updateHostComponent(current, workInProgress, renderExpirationTime);
1337 case HostText:
1338 return updateHostText(current, workInProgress);
1345 - case PlaceholderComponent:
1346 - return updatePlaceholderComponent(
1339 + case SuspenseComponent:
1340 + return updateSuspenseComponent(
1341 current,
1342 workInProgress,
1343 renderExpirationTime,
packages/react-reconciler/src/ReactFiberCommitWork.js
+16 -19
@@ -22,7 +22,6 @@ import type {CapturedValue, CapturedError} from './ReactCapturedValue';
22 import {
23 enableSchedulerTracing,
24 enableProfilerTimer,
25 - enableSuspense,
25 } from 'shared/ReactFeatureFlags';
26 import {
27 ClassComponent,
@@ -32,7 +31,7 @@ import {
31 HostText,
32 HostPortal,
33 Profiler,
35 - PlaceholderComponent,
34 + SuspenseComponent,
35 } from 'shared/ReactWorkTags';
36 import {
37 invokeGuardedCallback,
@@ -352,22 +351,20 @@ function commitLifeCycles(
351 }
352 return;
353 }
355 - case PlaceholderComponent: {
356 - if (enableSuspense) {
357 - if ((finishedWork.mode & StrictMode) === NoEffect) {
358 - // In loose mode, a placeholder times out by scheduling a synchronous
359 - // update in the commit phase. Use `updateQueue` field to signal that
360 - // the Timeout needs to switch to the placeholder. We don't need an
361 - // entire queue. Any non-null value works.
362 - // $FlowFixMe - Intentionally using a value other than an UpdateQueue.
363 - finishedWork.updateQueue = emptyObject;
364 - scheduleWork(finishedWork, Sync);
365 - } else {
366 - // In strict mode, the Update effect is used to record the time at
367 - // which the placeholder timed out.
368 - const currentTime = requestCurrentTime();
369 - finishedWork.stateNode = {timedOutAt: currentTime};
370 - }
354 + case SuspenseComponent: {
355 + if ((finishedWork.mode & StrictMode) === NoEffect) {
356 + // In loose mode, a placeholder times out by scheduling a synchronous
357 + // update in the commit phase. Use `updateQueue` field to signal that
358 + // the Timeout needs to switch to the placeholder. We don't need an
359 + // entire queue. Any non-null value works.
360 + // $FlowFixMe - Intentionally using a value other than an UpdateQueue.
361 + finishedWork.updateQueue = emptyObject;
362 + scheduleWork(finishedWork, Sync);
363 + } else {
364 + // In strict mode, the Update effect is used to record the time at
365 + // which the placeholder timed out.
366 + const currentTime = requestCurrentTime();
367 + finishedWork.stateNode = {timedOutAt: currentTime};
368 }
369 return;
370 }
@@ -863,7 +860,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
860 case Profiler: {
861 return;
862 }
866 - case PlaceholderComponent: {
863 + case SuspenseComponent: {
864 return;
865 }
866 default: {
packages/react-reconciler/src/ReactFiberCompleteWork.js
+2 -2
@@ -34,7 +34,7 @@ import {
34 Fragment,
35 Mode,
36 Profiler,
37 - PlaceholderComponent,
37 + SuspenseComponent,
38 ForwardRefLazy,
39 PureComponent,
40 PureComponentLazy,
@@ -508,7 +508,7 @@ function completeWork(
508 case ForwardRef:
509 case ForwardRefLazy:
510 break;
511 - case PlaceholderComponent:
511 + case SuspenseComponent:
512 break;
513 case Fragment:
514 break;
packages/react-reconciler/src/ReactFiberScheduler.js
+42 -47
@@ -49,7 +49,6 @@ import {
49 enableUserTimingAPI,
50 replayFailedUnitOfWorkWithInvokeGuardedCallback,
51 warnAboutDeprecatedLifecycles,
52 - enableSuspense,
52 } from 'shared/ReactFeatureFlags';
53 import getComponentName from 'shared/getComponentName';
54 import invariant from 'shared/invariant';
@@ -1374,7 +1373,7 @@ function renderRoot(
1373 }
1374 }
1375
1377 - if (enableSuspense && !isExpired && nextLatestAbsoluteTimeoutMs !== -1) {
1376 + if (!isExpired && nextLatestAbsoluteTimeoutMs !== -1) {
1377 // The tree was suspended.
1378 const suspendedExpirationTime = expirationTime;
1379 markSuspendedPriorityLevel(root, suspendedExpirationTime);
@@ -1567,42 +1566,40 @@ function retrySuspendedRoot(
1566 fiber: Fiber,
1567 suspendedTime: ExpirationTime,
1568 ) {
1570 - if (enableSuspense) {
1571 - let retryTime;
1569 + let retryTime;
1570
1573 - if (isPriorityLevelSuspended(root, suspendedTime)) {
1574 - // Ping at the original level
1575 - retryTime = suspendedTime;
1571 + if (isPriorityLevelSuspended(root, suspendedTime)) {
1572 + // Ping at the original level
1573 + retryTime = suspendedTime;
1574
1577 - markPingedPriorityLevel(root, retryTime);
1578 - } else {
1579 - // Placeholder already timed out. Compute a new expiration time
1580 - const currentTime = requestCurrentTime();
1581 - retryTime = computeExpirationForFiber(currentTime, fiber);
1582 - markPendingPriorityLevel(root, retryTime);
1583 - }
1584 -
1585 - // TODO: If the placeholder fiber has already rendered the primary children
1586 - // without suspending (that is, all of the promises have already resolved),
1587 - // we should not trigger another update here. One case this happens is when
1588 - // we are in sync mode and a single promise is thrown both on initial render
1589 - // and on update; we attach two .then(retrySuspendedRoot) callbacks and each
1590 - // one performs Sync work, rerendering the Placeholder.
1591 -
1592 - if ((fiber.mode & ConcurrentMode) !== NoContext) {
1593 - if (root === nextRoot && nextRenderExpirationTime === suspendedTime) {
1594 - // Received a ping at the same priority level at which we're currently
1595 - // rendering. Restart from the root.
1596 - nextRoot = null;
1597 - }
1598 - }
1575 + markPingedPriorityLevel(root, retryTime);
1576 + } else {
1577 + // Suspense already timed out. Compute a new expiration time
1578 + const currentTime = requestCurrentTime();
1579 + retryTime = computeExpirationForFiber(currentTime, fiber);
1580 + markPendingPriorityLevel(root, retryTime);
1581 + }
1582
1600 - scheduleWorkToRoot(fiber, retryTime);
1601 - const rootExpirationTime = root.expirationTime;
1602 - if (rootExpirationTime !== NoWork) {
1603 - requestWork(root, rootExpirationTime);
1583 + // TODO: If the placeholder fiber has already rendered the primary children
1584 + // without suspending (that is, all of the promises have already resolved),
1585 + // we should not trigger another update here. One case this happens is when
1586 + // we are in sync mode and a single promise is thrown both on initial render
1587 + // and on update; we attach two .then(retrySuspendedRoot) callbacks and each
1588 + // one performs Sync work, rerendering the Suspense.
1589 +
1590 + if ((fiber.mode & ConcurrentMode) !== NoContext) {
1591 + if (root === nextRoot && nextRenderExpirationTime === suspendedTime) {
1592 + // Received a ping at the same priority level at which we're currently
1593 + // rendering. Restart from the root.
1594 + nextRoot = null;
1595 }
1596 }
1597 +
1598 + scheduleWorkToRoot(fiber, retryTime);
1599 + const rootExpirationTime = root.expirationTime;
1600 + if (rootExpirationTime !== NoWork) {
1601 + requestWork(root, rootExpirationTime);
1602 + }
1603 }
1604
1605 function scheduleWorkToRoot(fiber: Fiber, expirationTime): FiberRoot | null {
@@ -1877,7 +1874,7 @@ function onSuspend(
1874 msUntilTimeout: number,
1875 ): void {
1876 root.expirationTime = rootExpirationTime;
1880 - if (enableSuspense && msUntilTimeout === 0 && !shouldYield()) {
1877 + if (msUntilTimeout === 0 && !shouldYield()) {
1878 // Don't wait an additional tick. Commit the tree immediately.
1879 root.pendingCommitExpirationTime = suspendedExpirationTime;
1880 root.finishedWork = finishedWork;
@@ -1895,17 +1892,15 @@ function onYield(root) {
1892 }
1893
1894 function onTimeout(root, finishedWork, suspendedExpirationTime) {
1898 - if (enableSuspense) {
1899 - // The root timed out. Commit it.
1900 - root.pendingCommitExpirationTime = suspendedExpirationTime;
1901 - root.finishedWork = finishedWork;
1902 - // Read the current time before entering the commit phase. We can be
1903 - // certain this won't cause tearing related to batching of event updates
1904 - // because we're at the top of a timer event.
1905 - recomputeCurrentRendererTime();
1906 - currentSchedulerTime = currentRendererTime;
1907 - flushRoot(root, suspendedExpirationTime);
1908 - }
1895 + // The root timed out. Commit it.
1896 + root.pendingCommitExpirationTime = suspendedExpirationTime;
1897 + root.finishedWork = finishedWork;
1898 + // Read the current time before entering the commit phase. We can be
1899 + // certain this won't cause tearing related to batching of event updates
1900 + // because we're at the top of a timer event.
1901 + recomputeCurrentRendererTime();
1902 + currentSchedulerTime = currentRendererTime;
1903 + flushRoot(root, suspendedExpirationTime);
1904 }
1905
1906 function onCommit(root, expirationTime) {
@@ -2247,7 +2242,7 @@ function performWorkOnRoot(
2242 // If this root previously suspended, clear its existing timeout, since
2243 // we're about to try rendering again.
2244 const timeoutHandle = root.timeoutHandle;
2250 - if (enableSuspense && timeoutHandle !== noTimeout) {
2245 + if (timeoutHandle !== noTimeout) {
2246 root.timeoutHandle = noTimeout;
2247 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
2248 cancelTimeout(timeoutHandle);
@@ -2271,7 +2266,7 @@ function performWorkOnRoot(
2266 // If this root previously suspended, clear its existing timeout, since
2267 // we're about to try rendering again.
2268 const timeoutHandle = root.timeoutHandle;
2274 - if (enableSuspense && timeoutHandle !== noTimeout) {
2269 + if (timeoutHandle !== noTimeout) {
2270 root.timeoutHandle = noTimeout;
2271 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
2272 cancelTimeout(timeoutHandle);
packages/react-reconciler/src/ReactFiberUnwindWork.js
+9 -10
@@ -26,7 +26,7 @@ import {
26 HostComponent,
27 HostPortal,
28 ContextProvider,
29 - PlaceholderComponent,
29 + SuspenseComponent,
30 } from 'shared/ReactWorkTags';
31 import {
32 DidCapture,
@@ -36,7 +36,7 @@ import {
36 Update as UpdateEffect,
37 LifecycleEffectMask,
38 } from 'shared/ReactSideEffectTags';
39 -import {enableSuspense, enableSchedulerTracing} from 'shared/ReactFeatureFlags';
39 +import {enableSchedulerTracing} from 'shared/ReactFeatureFlags';
40 import {StrictMode, ConcurrentMode} from './ReactTypeOfMode';
41
42 import {createCapturedValue} from './ReactCapturedValue';
@@ -158,7 +158,6 @@ function throwException(
158 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
159
160 if (
161 - enableSuspense &&
161 value !== null &&
162 typeof value === 'object' &&
163 typeof value.then === 'function'
@@ -175,7 +174,7 @@ function throwException(
174 let earliestTimeoutMs = -1;
175 let startTimeMs = -1;
176 do {
178 - if (workInProgress.tag === PlaceholderComponent) {
177 + if (workInProgress.tag === SuspenseComponent) {
178 const current = workInProgress.alternate;
179 if (
180 current !== null &&
@@ -193,7 +192,7 @@ function throwException(
192 // Do not search any further.
193 break;
194 }
196 - let timeoutPropMs = workInProgress.pendingProps.delayMs;
195 + let timeoutPropMs = workInProgress.pendingProps.maxDuration;
196 if (typeof timeoutPropMs === 'number') {
197 if (timeoutPropMs <= 0) {
198 earliestTimeoutMs = 0;
@@ -208,10 +207,10 @@ function throwException(
207 workInProgress = workInProgress.return;
208 } while (workInProgress !== null);
209
211 - // Schedule the nearest Placeholder to re-render the timed out view.
210 + // Schedule the nearest Suspense to re-render the timed out view.
211 workInProgress = returnFiber;
212 do {
214 - if (workInProgress.tag === PlaceholderComponent) {
213 + if (workInProgress.tag === SuspenseComponent) {
214 const didTimeout = workInProgress.memoizedState;
215 if (!didTimeout) {
216 // Found the nearest boundary.
@@ -238,10 +237,10 @@ function throwException(
237 // If the boundary is outside of strict mode, we should *not* suspend
238 // the commit. Pretend as if the suspended component rendered null and
239 // keep rendering. In the commit phase, we'll schedule a subsequent
241 - // synchronous update to re-render the Placeholder.
240 + // synchronous update to re-render the Suspense.
241 //
242 // Note: It doesn't matter whether the component that suspended was
244 - // inside a strict mode tree. If the Placeholder is outside of it, we
243 + // inside a strict mode tree. If the Suspense is outside of it, we
244 // should *not* suspend the commit.
245 if ((workInProgress.mode & StrictMode) === NoEffect) {
246 workInProgress.effectTag |= UpdateEffect;
@@ -434,7 +433,7 @@ function unwindWork(
433 popHostContext(workInProgress);
434 return null;
435 }
437 - case PlaceholderComponent: {
436 + case SuspenseComponent: {
437 const effectTag = workInProgress.effectTag;
438 if (effectTag & ShouldCapture) {
439 workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture;
packages/react-reconciler/src/__tests__/ReactPure-test.internal.js
+17 -18
@@ -21,7 +21,6 @@ describe('pure', () => {
21 jest.resetModules();
22 ReactFeatureFlags = require('shared/ReactFeatureFlags');
23 ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;
24 - ReactFeatureFlags.enableSuspense = true;
24 React = require('react');
25 ReactNoop = require('react-noop-renderer');
26 });
@@ -50,7 +49,7 @@ describe('pure', () => {
49 function sharedTests(label, pure) {
50 describe(`${label}`, () => {
51 it('bails out on props equality', async () => {
53 - const {Placeholder} = React;
52 + const {unstable_Suspense: Suspense} = React;
53
54 function Counter({count}) {
55 return <Text text={count} />;
@@ -58,9 +57,9 @@ describe('pure', () => {
57 Counter = pure(Counter);
58
59 ReactNoop.render(
61 - <Placeholder>
60 + <Suspense>
61 <Counter count={0} />
63 - </Placeholder>,
62 + </Suspense>,
63 );
64 expect(ReactNoop.flush()).toEqual([]);
65 await Promise.resolve();
@@ -69,18 +68,18 @@ describe('pure', () => {
68
69 // Should bail out because props have not changed
70 ReactNoop.render(
72 - <Placeholder>
71 + <Suspense>
72 <Counter count={0} />
74 - </Placeholder>,
73 + </Suspense>,
74 );
75 expect(ReactNoop.flush()).toEqual([]);
76 expect(ReactNoop.getChildren()).toEqual([span(0)]);
77
78 // Should update because count prop changed
79 ReactNoop.render(
81 - <Placeholder>
80 + <Suspense>
81 <Counter count={1} />
83 - </Placeholder>,
82 + </Suspense>,
83 );
84 expect(ReactNoop.flush()).toEqual([1]);
85 expect(ReactNoop.getChildren()).toEqual([span(1)]);
@@ -88,7 +87,7 @@ describe('pure', () => {
87 });
88
89 it("does not bail out if there's a context change", async () => {
91 - const {Placeholder} = React;
90 + const {unstable_Suspense: Suspense} = React;
91
92 const CountContext = React.createContext(0);
93
@@ -102,11 +101,11 @@ describe('pure', () => {
101 state = {count: 0};
102 render() {
103 return (
105 - <Placeholder>
104 + <Suspense>
105 <CountContext.Provider value={this.state.count}>
106 <Counter label="Count" />
107 </CountContext.Provider>
109 - </Placeholder>
108 + </Suspense>
109 );
110 }
111 }
@@ -130,7 +129,7 @@ describe('pure', () => {
129 });
130
131 it('accepts custom comparison function', async () => {
133 - const {Placeholder} = React;
132 + const {unstable_Suspense: Suspense} = React;
133
134 function Counter({count}) {
135 return <Text text={count} />;
@@ -143,9 +142,9 @@ describe('pure', () => {
142 });
143
144 ReactNoop.render(
146 - <Placeholder>
145 + <Suspense>
146 <Counter count={0} />
148 - </Placeholder>,
147 + </Suspense>,
148 );
149 expect(ReactNoop.flush()).toEqual([]);
150 await Promise.resolve();
@@ -154,18 +153,18 @@ describe('pure', () => {
153
154 // Should bail out because props have not changed
155 ReactNoop.render(
157 - <Placeholder>
156 + <Suspense>
157 <Counter count={0} />
159 - </Placeholder>,
158 + </Suspense>,
159 );
160 expect(ReactNoop.flush()).toEqual(['Old count: 0, New count: 0']);
161 expect(ReactNoop.getChildren()).toEqual([span(0)]);
162
163 // Should update because count prop changed
164 ReactNoop.render(
166 - <Placeholder>
165 + <Suspense>
166 <Counter count={1} />
168 - </Placeholder>,
167 + </Suspense>,
168 );
169 expect(ReactNoop.flush()).toEqual(['Old count: 0, New count: 1', 1]);
170 expect(ReactNoop.getChildren()).toEqual([span(1)]);
packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js
+14 -15
@@ -2,7 +2,7 @@ let React;
2 let ReactTestRenderer;
3 let ReactFeatureFlags;
4 let ReactCache;
5 -let Placeholder;
5 +let Suspense;
6
7 // let JestReact;
8
@@ -18,13 +18,12 @@ describe('ReactSuspense', () => {
18 ReactFeatureFlags = require('shared/ReactFeatureFlags');
19 ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;
20 ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
21 - ReactFeatureFlags.enableSuspense = true;
21 React = require('react');
22 ReactTestRenderer = require('react-test-renderer');
23 // JestReact = require('jest-react');
24 ReactCache = require('react-cache');
25
27 - Placeholder = React.Placeholder;
26 + Suspense = React.unstable_Suspense;
27
28 function invalidateCache() {
29 cache = ReactCache.createCache(invalidateCache);
@@ -107,12 +106,12 @@ describe('ReactSuspense', () => {
106 function Foo() {
107 ReactTestRenderer.unstable_yield('Foo');
108 return (
110 - <Placeholder>
109 + <Suspense>
110 <Bar>
111 <AsyncText text="A" ms={100} />
112 <Text text="B" />
113 </Bar>
115 - </Placeholder>
114 + </Suspense>
115 );
116 }
117
@@ -145,15 +144,15 @@ describe('ReactSuspense', () => {
144 });
145
146 it('suspends siblings and later recovers each independently', () => {
148 - // Render two sibling Placeholder components
147 + // Render two sibling Suspense components
148 const root = ReactTestRenderer.create(
149 <React.Fragment>
151 - <Placeholder delayMs={1000} fallback={<Text text="Loading A..." />}>
150 + <Suspense maxDuration={1000} fallback={<Text text="Loading A..." />}>
151 <AsyncText text="A" ms={5000} />
153 - </Placeholder>
154 - <Placeholder delayMs={3000} fallback={<Text text="Loading B..." />}>
152 + </Suspense>
153 + <Suspense maxDuration={3000} fallback={<Text text="Loading B..." />}>
154 <AsyncText text="B" ms={6000} />
156 - </Placeholder>
155 + </Suspense>
156 </React.Fragment>,
157 {
158 unstable_isConcurrent: true,
@@ -173,8 +172,8 @@ describe('ReactSuspense', () => {
172 expect(root).toFlushWithoutYielding();
173 expect(root).toMatchRenderedOutput('Loading A...Loading B...');
174
176 - // Advance time by enough that the first Placeholder's promise resolves and
177 - // switches back to the normal view. The second Placeholder should still
175 + // Advance time by enough that the first Suspense's promise resolves and
176 + // switches back to the normal view. The second Suspense should still
177 // show the placeholder
178 jest.advanceTimersByTime(1000);
179 // TODO: Should we throw if you forget to call toHaveYielded?
@@ -182,7 +181,7 @@ describe('ReactSuspense', () => {
181 expect(root).toFlushAndYield(['A']);
182 expect(root).toMatchRenderedOutput('ALoading B...');
183
185 - // Advance time by enough that the second Placeholder's promise resolves
184 + // Advance time by enough that the second Suspense's promise resolves
185 // and switches back to the normal view
186 jest.advanceTimersByTime(1000);
187 expect(ReactTestRenderer).toHaveYielded(['Promise resolved [B]']);
@@ -219,10 +218,10 @@ describe('ReactSuspense', () => {
218 }
219
220 const root = ReactTestRenderer.create(
222 - <Placeholder delayMs={1000} fallback={<Text text="Loading..." />}>
221 + <Suspense maxDuration={1000} fallback={<Text text="Loading..." />}>
222 <Async />
223 <Text text="Sibling" />
225 - </Placeholder>,
224 + </Suspense>,
225 {
226 unstable_isConcurrent: true,
227 },
packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.internal.js
+106 -101
@@ -3,7 +3,7 @@ let ReactFeatureFlags;
3 let Fragment;
4 let ReactNoop;
5 let ReactCache;
6 -let Placeholder;
6 +let Suspense;
7 let StrictMode;
8 let ConcurrentMode;
9 let lazy;
@@ -21,12 +21,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
21 ReactFeatureFlags = require('shared/ReactFeatureFlags');
22 ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;
23 ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
24 - ReactFeatureFlags.enableSuspense = true;
24 React = require('react');
25 Fragment = React.Fragment;
26 ReactNoop = require('react-noop-renderer');
27 ReactCache = require('react-cache');
29 - Placeholder = React.Placeholder;
28 + Suspense = React.unstable_Suspense;
29 StrictMode = React.StrictMode;
30 ConcurrentMode = React.unstable_ConcurrentMode;
31 lazy = React.lazy;
@@ -103,12 +102,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
102 function Foo() {
103 ReactNoop.yield('Foo');
104 return (
106 - <Placeholder>
105 + <Suspense>
106 <Bar>
107 <AsyncText text="A" ms={100} />
108 <Text text="B" />
109 </Bar>
111 - </Placeholder>
110 + </Suspense>
111 );
112 }
113
@@ -143,15 +142,15 @@ describe('ReactSuspenseWithNoopRenderer', () => {
142 });
143
144 it('suspends siblings and later recovers each independently', async () => {
146 - // Render two sibling Placeholder components
145 + // Render two sibling Suspense components
146 ReactNoop.render(
147 <Fragment>
149 - <Placeholder delayMs={1000} fallback={<Text text="Loading A..." />}>
148 + <Suspense maxDuration={1000} fallback={<Text text="Loading A..." />}>
149 <AsyncText text="A" ms={5000} />
151 - </Placeholder>
152 - <Placeholder delayMs={3000} fallback={<Text text="Loading B..." />}>
150 + </Suspense>
151 + <Suspense maxDuration={3000} fallback={<Text text="Loading B..." />}>
152 <AsyncText text="B" ms={6000} />
154 - </Placeholder>
153 + </Suspense>
154 </Fragment>,
155 );
156 expect(ReactNoop.flush()).toEqual([
@@ -172,8 +171,8 @@ describe('ReactSuspenseWithNoopRenderer', () => {
171 span('Loading B...'),
172 ]);
173
175 - // Advance time by enough that the first Placeholder's promise resolves and
176 - // switches back to the normal view. The second Placeholder should still
174 + // Advance time by enough that the first Suspense's promise resolves and
175 + // switches back to the normal view. The second Suspense should still
176 // show the placeholder
177 ReactNoop.expire(1000);
178 await advanceTimers(1000);
@@ -181,7 +180,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
180 expect(ReactNoop.flush()).toEqual(['Promise resolved [A]', 'A']);
181 expect(ReactNoop.getChildren()).toEqual([span('A'), span('Loading B...')]);
182
184 - // Advance time by enough that the second Placeholder's promise resolves
183 + // Advance time by enough that the second Suspense's promise resolves
184 // and switches back to the normal view
185 ReactNoop.expire(1000);
186 await advanceTimers(1000);
@@ -192,12 +191,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
191
192 it('continues rendering siblings after suspending', async () => {
193 ReactNoop.render(
195 - <Placeholder>
194 + <Suspense>
195 <Text text="A" />
196 <AsyncText text="B" />
197 <Text text="C" />
198 <Text text="D" />
200 - </Placeholder>,
199 + </Suspense>,
200 );
201 // B suspends. Continue rendering the remaining siblings.
202 expect(ReactNoop.flush()).toEqual(['A', 'Suspend! [B]', 'C', 'D']);
@@ -242,11 +241,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
241 const errorBoundary = React.createRef();
242 function App() {
243 return (
245 - <Placeholder>
244 + <Suspense>
245 <ErrorBoundary ref={errorBoundary}>
246 <AsyncText text="Result" ms={1000} />
247 </ErrorBoundary>
249 - </Placeholder>
248 + </Suspense>
249 );
250 }
251
@@ -304,11 +303,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
303 const errorBoundary = React.createRef();
304 function App() {
305 return (
307 - <Placeholder delayMs={1000} fallback={<Text text="Loading..." />}>
306 + <Suspense maxDuration={1000} fallback={<Text text="Loading..." />}>
307 <ErrorBoundary ref={errorBoundary}>
308 <AsyncText text="Result" ms={3000} />
309 </ErrorBoundary>
311 - </Placeholder>
310 + </Suspense>
311 );
312 }
313
@@ -355,10 +354,10 @@ describe('ReactSuspenseWithNoopRenderer', () => {
354 it('can update at a higher priority while in a suspended state', async () => {
355 function App(props) {
356 return (
358 - <Placeholder>
357 + <Suspense>
358 <Text text={props.highPri} />
359 <AsyncText text={props.lowPri} />
361 - </Placeholder>
360 + </Suspense>
361 );
362 }
363
@@ -394,10 +393,10 @@ describe('ReactSuspenseWithNoopRenderer', () => {
393 it('keeps working on lower priority work after being pinged', async () => {
394 function App(props) {
395 return (
397 - <Placeholder>
396 + <Suspense>
397 <AsyncText text="A" />
398 {props.showB && <Text text="B" />}
400 - </Placeholder>
399 + </Suspense>
400 );
401 }
402
@@ -422,9 +421,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
421 return <Text text="(empty)" />;
422 }
423 return (
425 - <Placeholder>
424 + <Suspense>
425 <AsyncText ms={2000} text="Async" />
427 - </Placeholder>
426 + </Suspense>
427 );
428 }
429
@@ -449,9 +448,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
448 it('forces an expiration after an update times out', async () => {
449 ReactNoop.render(
450 <Fragment>
452 - <Placeholder fallback={<Text text="Loading..." />}>
451 + <Suspense fallback={<Text text="Loading..." />}>
452 <AsyncText text="Async" ms={20000} />
454 - </Placeholder>
453 + </Suspense>
454 <Text text="Sync" />
455 </Fragment>,
456 );
@@ -487,14 +486,16 @@ describe('ReactSuspenseWithNoopRenderer', () => {
486 ReactNoop.render(
487 <Fragment>
488 <Text text="Sync" />
490 - <Placeholder delayMs={1000} fallback={<Text text="Loading outer..." />}>
489 + <Suspense
490 + maxDuration={1000}
491 + fallback={<Text text="Loading outer..." />}>
492 <AsyncText text="Outer content" ms={2000} />
492 - <Placeholder
493 - delayMs={2500}
493 + <Suspense
494 + maxDuration={2500}
495 fallback={<Text text="Loading inner..." />}>
496 <AsyncText text="Inner content" ms={5000} />
496 - </Placeholder>
497 - </Placeholder>
497 + </Suspense>
498 + </Suspense>
499 </Fragment>,
500 );
501
@@ -568,9 +569,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
569 ReactNoop.flushSync(() =>
570 ReactNoop.render(
571 <Fragment>
571 - <Placeholder fallback={<Text text="Loading..." />}>
572 + <Suspense fallback={<Text text="Loading..." />}>
573 <AsyncText text="Async" />
573 - </Placeholder>
574 + </Suspense>
575 <Text text="Sync" />
576 </Fragment>,
577 ),
@@ -596,12 +597,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
597 ReactNoop.flushSync(() =>
598 ReactNoop.render(
599 <Fragment>
599 - <Placeholder fallback={<Text text="Loading (outer)..." />}>
600 - <Placeholder fallback={<AsyncText text="Loading (inner)..." />}>
600 + <Suspense fallback={<Text text="Loading (outer)..." />}>
601 + <Suspense fallback={<AsyncText text="Loading (inner)..." />}>
602 <AsyncText text="Async" />
602 - </Placeholder>
603 + </Suspense>
604 <Text text="Sync" />
604 - </Placeholder>
605 + </Suspense>
606 </Fragment>,
607 ),
608 );
@@ -615,12 +616,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
616 expect(ReactNoop.getChildren()).toEqual([span('Loading (outer)...')]);
617 });
618
618 - it('expires early with a `delayMs` option', async () => {
619 + it('expires early with a `maxDuration` option', async () => {
620 ReactNoop.render(
621 <Fragment>
621 - <Placeholder delayMs={1000} fallback={<Text text="Loading..." />}>
622 + <Suspense maxDuration={1000} fallback={<Text text="Loading..." />}>
623 <AsyncText text="Async" ms={3000} />
623 - </Placeholder>
624 + </Suspense>
625 <Text text="Sync" />
626 </Fragment>,
627 );
@@ -651,9 +652,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
652
653 it('resolves successfully even if fallback render is pending', async () => {
654 ReactNoop.render(
654 - <Placeholder delayMs={1000} fallback={<Text text="Loading..." />}>
655 + <Suspense maxDuration={1000} fallback={<Text text="Loading..." />}>
656 <AsyncText text="Async" ms={3000} />
656 - </Placeholder>,
657 + </Suspense>,
658 );
659 expect(ReactNoop.flushNextYield()).toEqual(['Suspend! [Async]']);
660 await advanceTimers(1500);
@@ -669,18 +670,18 @@ describe('ReactSuspenseWithNoopRenderer', () => {
670 expect(() => {
671 ReactNoop.flushSync(() =>
672 ReactNoop.render(
672 - <Placeholder>{() => <AsyncText text="Async" />}</Placeholder>,
673 + <Suspense>{() => <AsyncText text="Async" />}</Suspense>,
674 ),
675 );
676 }).toThrow('An update was suspended, but no placeholder UI was provided.');
677 });
678
678 - it('a Placeholder component correctly handles more than one suspended child', async () => {
679 + it('a Suspense component correctly handles more than one suspended child', async () => {
680 ReactNoop.render(
680 - <Placeholder delayMs={0}>
681 + <Suspense maxDuration={0}>
682 <AsyncText text="A" ms={100} />
683 <AsyncText text="B" ms={100} />
683 - </Placeholder>,
684 + </Suspense>,
685 );
686 expect(ReactNoop.expire(10000)).toEqual(['Suspend! [A]', 'Suspend! [B]']);
687 expect(ReactNoop.getChildren()).toEqual([]);
@@ -698,9 +699,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
699
700 it('can resume rendering earlier than a timeout', async () => {
701 ReactNoop.render(
701 - <Placeholder delayMs={1000} fallback={<Text text="Loading..." />}>
702 + <Suspense maxDuration={1000} fallback={<Text text="Loading..." />}>
703 <AsyncText text="Async" ms={100} />
703 - </Placeholder>,
704 + </Suspense>,
705 );
706 expect(ReactNoop.flush()).toEqual(['Suspend! [Async]', 'Loading...']);
707 expect(ReactNoop.getChildren()).toEqual([]);
@@ -723,13 +724,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
724 it('starts working on an update even if its priority falls between two suspended levels', async () => {
725 function App(props) {
726 return (
726 - <Placeholder delayMs={10000}>
727 + <Suspense maxDuration={10000}>
728 {props.text === 'C' ? (
729 <Text text="C" />
730 ) : (
731 <AsyncText text={props.text} ms={10000} />
732 )}
732 - </Placeholder>
733 + </Suspense>
734 );
735 }
736
@@ -772,7 +773,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
773 it('can hide a tree to unblock its surroundings', async () => {
774 function App() {
775 return (
775 - <Placeholder delayMs={1000}>
776 + <Suspense maxDuration={1000}>
777 {didTimeout => (
778 <Fragment>
779 <div hidden={didTimeout}>
@@ -781,7 +782,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
782 {didTimeout ? <Text text="Loading..." /> : null}
783 </Fragment>
784 )}
784 - </Placeholder>
785 + </Suspense>
786 );
787 }
788
@@ -811,9 +812,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
812 }
813 render() {
814 return (
814 - <Placeholder fallback={<Text text="Loading..." />}>
815 + <Suspense fallback={<Text text="Loading..." />}>
816 <AsyncText ms={20000} text={this.props.text} />
816 - </Placeholder>
817 + </Suspense>
818 );
819 }
820 }
@@ -852,13 +853,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
853 function Never() {
854 // Throws a promise that resolves after some arbitrarily large
855 // number of seconds. The idea is that this component will never
855 - // resolve. It's always wrapped by a Placeholder.
856 + // resolve. It's always wrapped by a Suspense.
857 throw new Promise(resolve => setTimeout(() => resolve(), 10000));
858 }
859
860 function Delay({ms}) {
861 return (
861 - <Placeholder delayMs={ms}>
862 + <Suspense maxDuration={ms}>
863 {didTimeout => {
864 if (didTimeout) {
865 // Once ms has elapsed, render null. This allows the rest of the
@@ -867,7 +868,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
868 }
869 return <Never />;
870 }}
870 - </Placeholder>
871 + </Suspense>
872 );
873 }
874
@@ -901,9 +902,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
902 it('times out immediately', async () => {
903 function App() {
904 return (
904 - <Placeholder delayMs={1000} fallback={<Text text="Loading..." />}>
905 + <Suspense maxDuration={1000} fallback={<Text text="Loading..." />}>
906 <AsyncText ms={100} text="Result" />
906 - </Placeholder>
907 + </Suspense>
908 );
909 }
910
@@ -924,7 +925,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
925 expect(ReactNoop.getChildren()).toEqual([span('Result')]);
926 });
927
927 - it('times out immediately when Placeholder is in loose mode, even if the suspender is async', async () => {
928 + it('times out immediately when Suspense is in loose mode, even if the suspender is async', async () => {
929 class UpdatingText extends React.Component {
930 state = {step: 1};
931 render() {
@@ -945,12 +946,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
946 const text = React.createRef(null);
947 function App() {
948 return (
948 - <Placeholder delayMs={1000} fallback={<Spinner />}>
949 + <Suspense maxDuration={1000} fallback={<Spinner />}>
950 <ConcurrentMode>
951 <UpdatingText ref={text} />
952 <Text text="Sibling" />
953 </ConcurrentMode>
953 - </Placeholder>
954 + </Suspense>
955 );
956 }
957
@@ -1022,7 +1023,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1023 function App() {
1024 return (
1025 <StrictMode>
1025 - <Placeholder delayMs={1000} fallback={<Text text="Loading..." />}>
1026 + <Suspense
1027 + maxDuration={1000}
1028 + fallback={<Text text="Loading..." />}>
1029 <ConcurrentMode>
1030 <UpdatingText ref={text1} initialText="Async: 1">
1031 {text => (
@@ -1034,7 +1037,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1037 )}
1038 </UpdatingText>
1039 </ConcurrentMode>
1037 - </Placeholder>
1040 + </Suspense>
1041 <ConcurrentMode>
1042 <UpdatingText ref={text2} initialText="Sync: 1">
1043 {text => (
@@ -1154,7 +1157,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1157 function App() {
1158 return (
1159 <Fragment>
1157 - <Placeholder delayMs={1000} fallback={<Text text="Loading..." />}>
1160 + <Suspense
1161 + maxDuration={1000}
1162 + fallback={<Text text="Loading..." />}>
1163 <ConcurrentMode>
1164 <UpdatingText ref={text1} initialText="Async: 1">
1165 {text => (
@@ -1166,7 +1171,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1171 )}
1172 </UpdatingText>
1173 </ConcurrentMode>
1169 - </Placeholder>
1174 + </Suspense>
1175 <ConcurrentMode>
1176 <UpdatingText ref={text2} initialText="Sync: 1">
1177 {text => (
@@ -1298,13 +1303,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1303
1304 function App() {
1305 return (
1301 - <Placeholder
1302 - delayMs={1000}
1306 + <Suspense
1307 + maxDuration={1000}
1308 fallback={<TextWithLifecycle text="Loading..." />}>
1309 <TextWithLifecycle text="A" />
1310 <AsyncTextWithLifecycle ms={100} text="B" />
1311 <TextWithLifecycle text="C" />
1307 - </Placeholder>
1312 + </Suspense>
1313 );
1314 }
1315
@@ -1371,9 +1376,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1376 }
1377
1378 ReactNoop.renderLegacySyncRoot(
1374 - <Placeholder fallback={<Text text="Loading..." />}>
1379 + <Suspense fallback={<Text text="Loading..." />}>
1380 <AsyncTextInConstructor ms={100} text="Hi" />
1376 - </Placeholder>,
1381 + </Suspense>,
1382 );
1383
1384 expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
@@ -1397,9 +1402,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1402 class Demo extends React.Component {
1403 render() {
1404 return (
1400 - <Placeholder fallback={<Fallback />}>
1405 + <Suspense fallback={<Fallback />}>
1406 <AsyncText text="Hi" ms={100} />
1402 - </Placeholder>
1407 + </Suspense>
1408 );
1409 }
1410 }
@@ -1416,9 +1421,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1421 const LazyText = Promise.resolve(Text);
1422
1423 ReactNoop.render(
1419 - <Placeholder fallback={<Text text="Loading..." />}>
1424 + <Suspense fallback={<Text text="Loading..." />}>
1425 <LazyText text="Hi" />
1421 - </Placeholder>,
1426 + </Suspense>,
1427 );
1428 expect(ReactNoop.flush()).toEqual(['Loading...']);
1429 expect(ReactNoop.getChildren()).toEqual([]);
@@ -1430,9 +1435,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1435
1436 // Should not suspend on update
1437 ReactNoop.render(
1433 - <Placeholder fallback={<Text text="Loading..." />}>
1438 + <Suspense fallback={<Text text="Loading..." />}>
1439 <LazyText text="Hi again" />
1435 - </Placeholder>,
1440 + </Suspense>,
1441 );
1442 expect(ReactNoop.flush()).toEqual(['Hi again']);
1443 expect(ReactNoop.getChildren()).toEqual([span('Hi again')]);
@@ -1442,9 +1447,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1447 const LazyText = Promise.reject(new Error('Bad network'));
1448
1449 ReactNoop.render(
1445 - <Placeholder fallback={<Text text="Loading..." />}>
1450 + <Suspense fallback={<Text text="Loading..." />}>
1451 <LazyText text="Hi" />
1447 - </Placeholder>,
1452 + </Suspense>,
1453 );
1454 expect(ReactNoop.flush()).toEqual(['Loading...']);
1455
@@ -1471,7 +1476,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1476
1477 function Parent({swap}) {
1478 return (
1474 - <Placeholder fallback={<Text text="Loading..." />}>
1479 + <Suspense fallback={<Text text="Loading..." />}>
1480 {swap
1481 ? [
1482 <LazyChildB key="B" label="B" />,
@@ -1481,7 +1486,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1486 <LazyChildA key="A" label="A" />,
1487 <LazyChildB key="B" label="B" />,
1488 ]}
1484 - </Placeholder>
1489 + </Suspense>
1490 );
1491 }
1492
@@ -1515,9 +1520,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1520 const LazyText = Promise.resolve({default: Text});
1521
1522 ReactNoop.render(
1518 - <Placeholder fallback={<Text text="Loading..." />}>
1523 + <Suspense fallback={<Text text="Loading..." />}>
1524 <LazyText text="Hi" />
1520 - </Placeholder>,
1525 + </Suspense>,
1526 );
1527 expect(ReactNoop.flush()).toEqual(['Loading...']);
1528 expect(ReactNoop.getChildren()).toEqual([]);
@@ -1529,9 +1534,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1534
1535 // Should not suspend on update
1536 ReactNoop.render(
1532 - <Placeholder fallback={<Text text="Loading..." />}>
1537 + <Suspense fallback={<Text text="Loading..." />}>
1538 <LazyText text="Hi again" />
1534 - </Placeholder>,
1539 + </Suspense>,
1540 );
1541 expect(ReactNoop.flush()).toEqual(['Hi again']);
1542 expect(ReactNoop.getChildren()).toEqual([span('Hi again')]);
@@ -1545,9 +1550,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1550 const LazyText = Promise.resolve(T);
1551
1552 ReactNoop.render(
1548 - <Placeholder fallback={<Text text="Loading..." />}>
1553 + <Suspense fallback={<Text text="Loading..." />}>
1554 <LazyText />
1550 - </Placeholder>,
1555 + </Suspense>,
1556 );
1557 expect(ReactNoop.flush()).toEqual(['Loading...']);
1558 expect(ReactNoop.getChildren()).toEqual([]);
@@ -1560,9 +1565,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1565 T.defaultProps = {text: 'Hi again'};
1566
1567 ReactNoop.render(
1563 - <Placeholder fallback={<Text text="Loading..." />}>
1568 + <Suspense fallback={<Text text="Loading..." />}>
1569 <LazyText text="Hi again" />
1565 - </Placeholder>,
1570 + </Suspense>,
1571 );
1572 expect(ReactNoop.flush()).toEqual(['Hi again']);
1573 expect(ReactNoop.getChildren()).toEqual([span('Hi again')]);
@@ -1590,11 +1595,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1595
1596 const stateful = React.createRef(null);
1597 ReactNoop.render(
1593 - <Placeholder fallback={<Text text="Loading..." />}>
1598 + <Suspense fallback={<Text text="Loading..." />}>
1599 <Lazy>
1600 <Stateful ref={stateful} />
1601 </Lazy>
1597 - </Placeholder>,
1602 + </Suspense>,
1603 );
1604 expect(ReactNoop.flush()).toEqual(['Loading...']);
1605 expect(ReactNoop.getChildren()).toEqual([]);
@@ -1615,11 +1620,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1620 });
1621
1622 ReactNoop.render(
1618 - <Placeholder fallback={<Text text="Loading..." />}>
1623 + <Suspense fallback={<Text text="Loading..." />}>
1624 <Text text="A" />
1625 <Text text="B" />
1626 <LazyText text="C" />
1622 - </Placeholder>,
1627 + </Suspense>,
1628 );
1629 // Render first two siblings. The lazy component should not have
1630 // started loading yet.
@@ -1649,9 +1654,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1654 });
1655
1656 ReactNoop.render(
1652 - <Placeholder fallback={<Text text="Loading..." />}>
1657 + <Suspense fallback={<Text text="Loading..." />}>
1658 <LazyFoo />
1654 - </Placeholder>,
1659 + </Suspense>,
1660 );
1661 expect(ReactNoop.flush()).toEqual(['Started loading', 'Loading...']);
1662 expect(ReactNoop.getChildren()).toEqual([]);
@@ -1682,10 +1687,10 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1687
1688 const ref = React.createRef();
1689 ReactNoop.render(
1685 - <Placeholder fallback={<Text text="Loading..." />}>
1690 + <Suspense fallback={<Text text="Loading..." />}>
1691 <LazyClass />
1692 <LazyForwardRef ref={ref} />
1688 - </Placeholder>,
1693 + </Suspense>,
1694 );
1695 expect(ReactNoop.flush()).toEqual(['Loading...']);
1696 expect(ReactNoop.getChildren()).toEqual([]);
@@ -1745,13 +1750,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
1750
1751 function App() {
1752 return (
1748 - <Placeholder
1749 - delayMs={1000}
1753 + <Suspense
1754 + maxDuration={1000}
1755 fallback={<TextWithLifecycle text="Loading..." />}>
1756 <TextWithLifecycle text="A" />
1757 <AsyncTextWithLifecycle ms={100} text="B" />
1758 <TextWithLifecycle text="C" />
1754 - </Placeholder>
1759 + </Suspense>
1760 );
1761 }
1762
packages/react/src/React.js
+3 -7
@@ -11,9 +11,8 @@ import {
11 REACT_FRAGMENT_TYPE,
12 REACT_PROFILER_TYPE,
13 REACT_STRICT_MODE_TYPE,
14 - REACT_PLACEHOLDER_TYPE,
14 + REACT_SUSPENSE_TYPE,
15 } from 'shared/ReactSymbols';
16 -import {enableSuspense} from 'shared/ReactFeatureFlags';
16
17 import {Component, PureComponent} from './ReactBaseClasses';
18 import {createRef} from './ReactCreateRef';
@@ -50,11 +49,13 @@ const React = {
49
50 createContext,
51 forwardRef,
52 + lazy,
53 pure,
54
55 Fragment: REACT_FRAGMENT_TYPE,
56 StrictMode: REACT_STRICT_MODE_TYPE,
57 unstable_ConcurrentMode: REACT_CONCURRENT_MODE_TYPE,
58 + unstable_Suspense: REACT_SUSPENSE_TYPE,
59 unstable_Profiler: REACT_PROFILER_TYPE,
60
61 createElement: __DEV__ ? createElementWithValidation : createElement,
@@ -67,9 +68,4 @@ const React = {
68 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: ReactSharedInternals,
69 };
70
70 -if (enableSuspense) {
71 - React.Placeholder = REACT_PLACEHOLDER_TYPE;
72 - React.lazy = lazy;
73 -}
74 -
71 export default React;
packages/react/src/__tests__/ReactProfiler-test.internal.js
+26 -29
@@ -21,7 +21,6 @@ let AdvanceTime;
21
22 function loadModules({
23 enableProfilerTimer = true,
24 - enableSuspense = false,
24 enableSchedulerTracing = true,
25 replayFailedUnitOfWorkWithInvokeGuardedCallback = false,
26 useNoopRenderer = false,
@@ -37,7 +36,6 @@ function loadModules({
36 ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;
37 ReactFeatureFlags.enableProfilerTimer = enableProfilerTimer;
38 ReactFeatureFlags.enableSchedulerTracing = enableSchedulerTracing;
40 - ReactFeatureFlags.enableSuspense = enableSuspense;
39 ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback = replayFailedUnitOfWorkWithInvokeGuardedCallback;
40
41 React = require('react');
@@ -1234,7 +1232,6 @@ describe('Profiler', () => {
1232 jest.resetModules();
1233
1234 loadModules({
1237 - enableSuspense: true,
1235 enableSchedulerTracing: true,
1236 ...params,
1237 });
@@ -2231,9 +2228,9 @@ describe('Profiler', () => {
2228 SchedulerTracing.unstable_trace(interaction.name, mockNow(), () => {
2229 ReactNoop.render(
2230 <React.unstable_Profiler id="test-profiler" onRender={onRender}>
2234 - <React.Placeholder fallback={<Text text="Loading..." />}>
2231 + <React.unstable_Suspense fallback={<Text text="Loading..." />}>
2232 <AsyncText text="Async" ms={20000} />
2236 - </React.Placeholder>
2233 + </React.unstable_Suspense>
2234 <Text text="Sync" />
2235 <Monkey ref={monkey} />
2236 </React.unstable_Profiler>,
@@ -2325,11 +2322,11 @@ describe('Profiler', () => {
2322 () => {
2323 ReactTestRenderer.create(
2324 <React.unstable_Profiler id="app" onRender={onRender}>
2328 - <React.Placeholder
2329 - delayMs={1000}
2325 + <React.unstable_Suspense
2326 + maxDuration={1000}
2327 fallback={<Text text="loading" />}>
2328 <AsyncText text="loaded" ms={2000} />
2332 - </React.Placeholder>
2329 + </React.unstable_Suspense>
2330 </React.unstable_Profiler>,
2331 );
2332 },
@@ -2379,11 +2376,11 @@ describe('Profiler', () => {
2376 () => {
2377 ReactTestRenderer.create(
2378 <React.unstable_Profiler id="app" onRender={onRender}>
2382 - <React.Placeholder
2383 - delayMs={1000}
2379 + <React.unstable_Suspense
2380 + maxDuration={1000}
2381 fallback={<Text text="loading" />}>
2382 <AsyncComponentWithCascadingWork text="loaded" ms={2000} />
2386 - </React.Placeholder>
2383 + </React.unstable_Suspense>
2384 </React.unstable_Profiler>,
2385 );
2386 },
@@ -2419,11 +2416,11 @@ describe('Profiler', () => {
2416 () => {
2417 renderer = ReactTestRenderer.create(
2418 <React.unstable_Profiler id="app" onRender={onRender}>
2422 - <React.Placeholder
2423 - delayMs={1000}
2419 + <React.unstable_Suspense
2420 + maxDuration={1000}
2421 fallback={<Text text="loading" />}>
2422 <AsyncText text="loaded" ms={2000} />
2426 - </React.Placeholder>
2423 + </React.unstable_Suspense>
2424 </React.unstable_Profiler>,
2425 {
2426 unstable_isConcurrent: true,
@@ -2467,11 +2464,11 @@ describe('Profiler', () => {
2464 () => {
2465 renderer = ReactTestRenderer.create(
2466 <React.unstable_Profiler id="app" onRender={onRender}>
2470 - <React.Placeholder
2471 - delayMs={2000}
2467 + <React.unstable_Suspense
2468 + maxDuration={2000}
2469 fallback={<Text text="loading" />}>
2470 <AsyncText text="loaded" ms={1000} />
2474 - </React.Placeholder>
2471 + </React.unstable_Suspense>
2472 </React.unstable_Profiler>,
2473 {unstable_isConcurrent: true},
2474 );
@@ -2506,11 +2503,11 @@ describe('Profiler', () => {
2503 () => {
2504 renderer = ReactTestRenderer.create(
2505 <React.unstable_Profiler id="app" onRender={onRender}>
2509 - <React.Placeholder
2510 - delayMs={2000}
2506 + <React.unstable_Suspense
2507 + maxDuration={2000}
2508 fallback={<Text text="loading" />}>
2509 <AsyncText text="loaded" ms={1000} />
2513 - </React.Placeholder>
2510 + </React.unstable_Suspense>
2511 <Text text="initial" />
2512 </React.unstable_Profiler>,
2513 );
@@ -2540,11 +2537,11 @@ describe('Profiler', () => {
2537 () => {
2538 renderer.update(
2539 <React.unstable_Profiler id="app" onRender={onRender}>
2543 - <React.Placeholder
2544 - delayMs={2000}
2540 + <React.unstable_Suspense
2541 + maxDuration={2000}
2542 fallback={<Text text="loading" />}>
2543 <AsyncText text="loaded" ms={1000} />
2547 - </React.Placeholder>
2544 + </React.unstable_Suspense>
2545 <Text text="updated" />
2546 </React.unstable_Profiler>,
2547 );
@@ -2602,11 +2599,11 @@ describe('Profiler', () => {
2599 () => {
2600 renderer = ReactTestRenderer.create(
2601 <React.unstable_Profiler id="app" onRender={onRender}>
2605 - <React.Placeholder
2606 - delayMs={2000}
2602 + <React.unstable_Suspense
2603 + maxDuration={2000}
2604 fallback={<Text text="loading" />}>
2605 <AsyncText text="loaded" ms={1000} />
2609 - </React.Placeholder>
2606 + </React.unstable_Suspense>
2607 <Text text="initial" />
2608 </React.unstable_Profiler>,
2609 {unstable_isConcurrent: true},
@@ -2640,11 +2637,11 @@ describe('Profiler', () => {
2637 () => {
2638 renderer.update(
2639 <React.unstable_Profiler id="app" onRender={onRender}>
2643 - <React.Placeholder
2644 - delayMs={2000}
2640 + <React.unstable_Suspense
2641 + maxDuration={2000}
2642 fallback={<Text text="loading" />}>
2643 <AsyncText text="loaded" ms={1000} />
2647 - </React.Placeholder>
2644 + </React.unstable_Suspense>
2645 <Text text="updated" />
2646 </React.unstable_Profiler>,
2647 );
packages/react/src/__tests__/ReactProfilerDOM-test.internal.js
+4 -3
@@ -50,7 +50,6 @@ function loadModules() {
50 ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;
51 ReactFeatureFlags.enableProfilerTimer = true;
52 ReactFeatureFlags.enableSchedulerTracing = true;
53 - ReactFeatureFlags.enableSuspense = true;
53
54 React = require('react');
55 SchedulerTracing = require('scheduler/tracing');
@@ -120,9 +119,11 @@ describe('ProfilerDOM', () => {
119 const root = ReactDOM.unstable_createRoot(element);
120 batch = root.createBatch();
121 batch.render(
123 - <React.Placeholder delayMS={100} fallback={<Text text="Loading..." />}>
122 + <React.unstable_Suspense
123 + maxDuration={100}
124 + fallback={<Text text="Loading..." />}>
125 <AsyncText text="Text" ms={200} />
125 - </React.Placeholder>,
126 + </React.unstable_Suspense>,
127 );
128 batch.then(
129 SchedulerTracing.unstable_wrap(() => {
packages/shared/ReactFeatureFlags.js
-3
@@ -7,11 +7,8 @@
7 * @flow strict
8 */
9
10 -// Exports ReactDOM.createRoot
10 export const enableUserTimingAPI = __DEV__;
11
13 -// Suspense
14 -export const enableSuspense = false;
12 // Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
13 export const debugRenderPhaseSideEffects = false;
14
packages/shared/ReactSymbols.js
+2 -2
@@ -38,8 +38,8 @@ export const REACT_CONCURRENT_MODE_TYPE = hasSymbol
38 export const REACT_FORWARD_REF_TYPE = hasSymbol
39 ? Symbol.for('react.forward_ref')
40 : 0xead0;
41 -export const REACT_PLACEHOLDER_TYPE = hasSymbol
42 - ? Symbol.for('react.placeholder')
41 +export const REACT_SUSPENSE_TYPE = hasSymbol
42 + ? Symbol.for('react.suspense')
43 : 0xead1;
44 export const REACT_PURE_TYPE = hasSymbol ? Symbol.for('react.pure') : 0xead3;
45
packages/shared/ReactWorkTags.js
+1 -1
@@ -44,6 +44,6 @@ export const ContextProvider = 12;
44 export const ForwardRef = 13;
45 export const ForwardRefLazy = 14;
46 export const Profiler = 15;
47 -export const PlaceholderComponent = 16;
47 +export const SuspenseComponent = 16;
48 export const PureComponent = 17;
49 export const PureComponentLazy = 18;
packages/shared/forks/ReactFeatureFlags.native-fabric-fb.js
-1
@@ -15,7 +15,6 @@ import typeof * as FabricFeatureFlagsType from './ReactFeatureFlags.native-fabri
15 export const debugRenderPhaseSideEffects = false;
16 export const debugRenderPhaseSideEffectsForStrictMode = false;
17 export const enableUserTimingAPI = __DEV__;
18 -export const enableSuspense = false;
18 export const warnAboutDeprecatedLifecycles = false;
19 export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
20 export const enableProfilerTimer = __PROFILE__;
packages/shared/forks/ReactFeatureFlags.native-fabric-oss.js
-1
@@ -15,7 +15,6 @@ import typeof * as FabricFeatureFlagsType from './ReactFeatureFlags.native-fabri
15 export const debugRenderPhaseSideEffects = false;
16 export const debugRenderPhaseSideEffectsForStrictMode = false;
17 export const enableUserTimingAPI = __DEV__;
18 -export const enableSuspense = false;
18 export const warnAboutDeprecatedLifecycles = false;
19 export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
20 export const enableProfilerTimer = __PROFILE__;
packages/shared/forks/ReactFeatureFlags.native-fb.js
-1
@@ -14,7 +14,6 @@ import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.native-fb';
14
15 // Re-export dynamic flags from the fbsource version.
16 export const {
17 - enableSuspense,
17 debugRenderPhaseSideEffects,
18 debugRenderPhaseSideEffectsForStrictMode,
19 warnAboutDeprecatedLifecycles,
packages/shared/forks/ReactFeatureFlags.native-oss.js
-1
@@ -14,7 +14,6 @@ import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.native-oss';
14
15 export const debugRenderPhaseSideEffects = false;
16 export const debugRenderPhaseSideEffectsForStrictMode = false;
17 -export const enableSuspense = false;
17 export const enableUserTimingAPI = __DEV__;
18 export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
19 export const warnAboutDeprecatedLifecycles = false;
packages/shared/forks/ReactFeatureFlags.persistent.js
-1
@@ -15,7 +15,6 @@ import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persiste
15 export const debugRenderPhaseSideEffects = false;
16 export const debugRenderPhaseSideEffectsForStrictMode = false;
17 export const enableUserTimingAPI = __DEV__;
18 -export const enableSuspense = false;
18 export const warnAboutDeprecatedLifecycles = false;
19 export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__;
20 export const enableProfilerTimer = __PROFILE__;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
-1
@@ -15,7 +15,6 @@ import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persiste
15 export const debugRenderPhaseSideEffects = false;
16 export const debugRenderPhaseSideEffectsForStrictMode = false;
17 export const enableUserTimingAPI = __DEV__;
18 -export const enableSuspense = false;
18 export const warnAboutDeprecatedLifecycles = false;
19 export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
20 export const enableProfilerTimer = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
-1
@@ -15,7 +15,6 @@ import typeof * as PersistentFeatureFlagsType from './ReactFeatureFlags.persiste
15 export const debugRenderPhaseSideEffects = false;
16 export const debugRenderPhaseSideEffectsForStrictMode = false;
17 export const enableUserTimingAPI = __DEV__;
18 -export const enableSuspense = true;
18 export const warnAboutDeprecatedLifecycles = false;
19 export const replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
20 export const enableProfilerTimer = false;
packages/shared/forks/ReactFeatureFlags.www.js
-1
@@ -12,7 +12,6 @@ import typeof * as FeatureFlagsShimType from './ReactFeatureFlags.www';
12
13 // Re-export dynamic flags from the www version.
14 export const {
15 - enableSuspense,
15 debugRenderPhaseSideEffects,
16 debugRenderPhaseSideEffectsForStrictMode,
17 enableSuspenseServerRenderer,
packages/shared/getComponentName.js
+3 -3
@@ -19,7 +19,7 @@ import {
19 REACT_PROFILER_TYPE,
20 REACT_PROVIDER_TYPE,
21 REACT_STRICT_MODE_TYPE,
22 - REACT_PLACEHOLDER_TYPE,
22 + REACT_SUSPENSE_TYPE,
23 } from 'shared/ReactSymbols';
24 import {refineResolvedThenable} from 'shared/ReactLazyComponent';
25
@@ -54,8 +54,8 @@ function getComponentName(type: mixed): string | null {
54 return `Profiler`;
55 case REACT_STRICT_MODE_TYPE:
56 return 'StrictMode';
57 - case REACT_PLACEHOLDER_TYPE:
58 - return 'Placeholder';
57 + case REACT_SUSPENSE_TYPE:
58 + return 'Suspense';
59 }
60 if (typeof type === 'object') {
61 switch (type.$$typeof) {
packages/shared/isValidElementType.js
+2 -2
@@ -15,7 +15,7 @@ import {
15 REACT_PROFILER_TYPE,
16 REACT_PROVIDER_TYPE,
17 REACT_STRICT_MODE_TYPE,
18 - REACT_PLACEHOLDER_TYPE,
18 + REACT_SUSPENSE_TYPE,
19 REACT_PURE_TYPE,
20 } from 'shared/ReactSymbols';
21
@@ -28,7 +28,7 @@ export default function isValidElementType(type: mixed) {
28 type === REACT_CONCURRENT_MODE_TYPE ||
29 type === REACT_PROFILER_TYPE ||
30 type === REACT_STRICT_MODE_TYPE ||
31 - type === REACT_PLACEHOLDER_TYPE ||
31 + type === REACT_SUSPENSE_TYPE ||
32 (typeof type === 'object' &&
33 type !== null &&
34 (typeof type.then === 'function' ||