Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Suspense + rename Placeholder #13799

Merged
merged 3 commits into from
Oct 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions fixtures/unstable-async/suspense/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,13 @@ No. The APIs being tested here are unstable and some of them have still not been

Clone the React repository.

First, open this file locally:

* `packages/shared/ReactFeatureFlags.js` (make sure you didn't open a similarly named file!)

Set [the `enableSuspense` flag](https://github.com/facebook/react/blob/d79238f1eeb6634ba7a3df23c3b2709b56cbb8b2/packages/shared/ReactFeatureFlags.js#L19) to `true` and save the file.

**After you've done that,** follow these steps:
Follow these steps:

```shell
# 1: Build react from source
cd /path/to/react
yarn
yarn build dom-client,core,react-cache,schedule --type=NODE
yarn build dom-client,core,react-cache,scheduler --type=NODE

# 2: Install fixture dependencies
cd fixtures/unstable-async/suspense/
Expand Down
10 changes: 5 additions & 5 deletions fixtures/unstable-async/suspense/src/components/App.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {Placeholder, PureComponent} from 'react';
import React, {unstable_Suspense as Suspense, PureComponent} from 'react';
import {unstable_scheduleCallback} from 'scheduler';
import {
unstable_trace as trace,
Expand Down Expand Up @@ -76,21 +76,21 @@ export default class App extends PureComponent {
}}>
Return to list
</button>
<Placeholder delayMs={2000} fallback={<Spinner size="large" />}>
<Suspense maxDuration={2000} fallback={<Spinner size="large" />}>
<UserPageLoader id={id} />
</Placeholder>
</Suspense>
</div>
);
}

renderList(loadingId) {
return (
<Placeholder delayMs={1500} fallback={<Spinner size="large" />}>
<Suspense maxDuration={1500} fallback={<Spinner size="large" />}>
<ContributorListPage
loadingId={loadingId}
onUserClick={this.handleUserClick}
/>
</Placeholder>
</Suspense>
);
}
}
10 changes: 5 additions & 5 deletions fixtures/unstable-async/suspense/src/components/UserPage.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {Placeholder} from 'react';
import React, {unstable_Suspense as Suspense} from 'react';
import {createResource} from 'react-cache';
import Spinner from './Spinner';
import {cache} from '../cache';
Expand All @@ -14,9 +14,9 @@ export default function UserPage({id}) {
alignItems: 'start',
}}>
<UserDetails id={id} />
<Placeholder delayMs={1000} fallback={<Spinner size="medium" />}>
<Suspense maxDuration={1000} fallback={<Spinner size="medium" />}>
<Repositories id={id} />
</Placeholder>
</Suspense>
</div>
);
}
Expand Down Expand Up @@ -118,7 +118,7 @@ function Img({src, alt, ...rest}) {

function UserPicture({source}) {
return (
<Placeholder delayMs={1500} fallback={<img src={source} alt="poster" />}>
<Suspense maxDuration={1500} fallback={<img src={source} alt="poster" />}>
<Img
src={source}
alt="profile picture"
Expand All @@ -128,7 +128,7 @@ function UserPicture({source}) {
borderRadius: '0.5rem',
}}
/>
</Placeholder>
</Suspense>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ function initModules() {
jest.resetModuleRegistry();

ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.enableSuspense = true;
ReactFeatureFlags.enableSuspenseServerRenderer = true;

React = require('react');
Expand All @@ -39,7 +38,7 @@ const {resetModules, serverRender} = ReactDOMServerIntegrationUtils(
initModules,
);

describe('ReactDOMServerPlaceholders', () => {
describe('ReactDOMServerSuspense', () => {
beforeEach(() => {
resetModules();
});
Expand All @@ -49,9 +48,9 @@ describe('ReactDOMServerPlaceholders', () => {
throw new Promise(() => {});
};
const e = await serverRender(
<React.Placeholder fallback={<div />}>
<React.unstable_Suspense fallback={<div />}>
<Suspended />
</React.Placeholder>,
</React.unstable_Suspense>,
);

expect(e.tagName).toBe('DIV');
Expand Down
4 changes: 2 additions & 2 deletions packages/react-dom/src/server/ReactPartialRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
REACT_FRAGMENT_TYPE,
REACT_STRICT_MODE_TYPE,
REACT_CONCURRENT_MODE_TYPE,
REACT_PLACEHOLDER_TYPE,
REACT_SUSPENSE_TYPE,
REACT_PORTAL_TYPE,
REACT_PROFILER_TYPE,
REACT_PROVIDER_TYPE,
Expand Down Expand Up @@ -916,7 +916,7 @@ class ReactDOMServerRenderer {
this.stack.push(frame);
return '';
}
case REACT_PLACEHOLDER_TYPE: {
case REACT_SUSPENSE_TYPE: {
if (enableSuspenseServerRenderer) {
const nextChildren = toArray(
// Always use the fallback when synchronously rendering to string.
Expand Down
8 changes: 4 additions & 4 deletions packages/react-reconciler/src/ReactFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
ContextProvider,
ContextConsumer,
Profiler,
PlaceholderComponent,
SuspenseComponent,
FunctionComponentLazy,
ClassComponentLazy,
ForwardRefLazy,
Expand All @@ -58,7 +58,7 @@ import {
REACT_PROVIDER_TYPE,
REACT_CONTEXT_TYPE,
REACT_CONCURRENT_MODE_TYPE,
REACT_PLACEHOLDER_TYPE,
REACT_SUSPENSE_TYPE,
REACT_PURE_TYPE,
} from 'shared/ReactSymbols';

Expand Down Expand Up @@ -442,8 +442,8 @@ export function createFiberFromElement(
break;
case REACT_PROFILER_TYPE:
return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
case REACT_PLACEHOLDER_TYPE:
fiberTag = PlaceholderComponent;
case REACT_SUSPENSE_TYPE:
fiberTag = SuspenseComponent;
break;
default: {
if (typeof type === 'object' && type !== null) {
Expand Down
16 changes: 5 additions & 11 deletions packages/react-reconciler/src/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
ContextProvider,
ContextConsumer,
Profiler,
PlaceholderComponent,
SuspenseComponent,
PureComponent,
PureComponentLazy,
} from 'shared/ReactWorkTags';
Expand All @@ -45,7 +45,6 @@ import {
} from 'shared/ReactSideEffectTags';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import {
enableSuspense,
debugRenderPhaseSideEffects,
debugRenderPhaseSideEffectsForStrictMode,
enableProfilerTimer,
Expand Down Expand Up @@ -935,18 +934,16 @@ function mountIndeterminateComponent(
}
}

function updatePlaceholderComponent(
function updateSuspenseComponent(
current,
workInProgress,
renderExpirationTime,
) {
if (enableSuspense) {
const nextProps = workInProgress.pendingProps;

// Check if we already attempted to render the normal state. If we did,
// and we timed out, render the placeholder state.
const alreadyCaptured =
(workInProgress.effectTag & DidCapture) === NoEffect;
const alreadyCaptured = (workInProgress.effectTag & DidCapture) === NoEffect;

let nextDidTimeout;
if (current !== null && workInProgress.updateQueue !== null) {
Expand Down Expand Up @@ -1003,9 +1000,6 @@ function updatePlaceholderComponent(
workInProgress.memoizedProps = nextProps;
workInProgress.memoizedState = nextDidTimeout;
return workInProgress.child;
} else {
return null;
}
}

function updatePortalComponent(
Expand Down Expand Up @@ -1342,8 +1336,8 @@ function beginWork(
return updateHostComponent(current, workInProgress, renderExpirationTime);
case HostText:
return updateHostText(current, workInProgress);
case PlaceholderComponent:
return updatePlaceholderComponent(
case SuspenseComponent:
return updateSuspenseComponent(
current,
workInProgress,
renderExpirationTime,
Expand Down
9 changes: 3 additions & 6 deletions packages/react-reconciler/src/ReactFiberCommitWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import type {CapturedValue, CapturedError} from './ReactCapturedValue';
import {
enableSchedulerTracing,
enableProfilerTimer,
enableSuspense,
} from 'shared/ReactFeatureFlags';
import {
ClassComponent,
Expand All @@ -32,7 +31,7 @@ import {
HostText,
HostPortal,
Profiler,
PlaceholderComponent,
SuspenseComponent,
} from 'shared/ReactWorkTags';
import {
invokeGuardedCallback,
Expand Down Expand Up @@ -352,8 +351,7 @@ function commitLifeCycles(
}
return;
}
case PlaceholderComponent: {
if (enableSuspense) {
case SuspenseComponent: {
if ((finishedWork.mode & StrictMode) === NoEffect) {
// In loose mode, a placeholder times out by scheduling a synchronous
// update in the commit phase. Use `updateQueue` field to signal that
Expand All @@ -368,7 +366,6 @@ function commitLifeCycles(
const currentTime = requestCurrentTime();
finishedWork.stateNode = {timedOutAt: currentTime};
}
}
return;
}
default: {
Expand Down Expand Up @@ -863,7 +860,7 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
case Profiler: {
return;
}
case PlaceholderComponent: {
case SuspenseComponent: {
return;
}
default: {
Expand Down
4 changes: 2 additions & 2 deletions packages/react-reconciler/src/ReactFiberCompleteWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
Fragment,
Mode,
Profiler,
PlaceholderComponent,
SuspenseComponent,
ForwardRefLazy,
PureComponent,
PureComponentLazy,
Expand Down Expand Up @@ -508,7 +508,7 @@ function completeWork(
case ForwardRef:
case ForwardRefLazy:
break;
case PlaceholderComponent:
case SuspenseComponent:
break;
case Fragment:
break;
Expand Down
17 changes: 6 additions & 11 deletions packages/react-reconciler/src/ReactFiberScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import {
enableUserTimingAPI,
replayFailedUnitOfWorkWithInvokeGuardedCallback,
warnAboutDeprecatedLifecycles,
enableSuspense,
} from 'shared/ReactFeatureFlags';
import getComponentName from 'shared/getComponentName';
import invariant from 'shared/invariant';
Expand Down Expand Up @@ -1374,7 +1373,7 @@ function renderRoot(
}
}

if (enableSuspense && !isExpired && nextLatestAbsoluteTimeoutMs !== -1) {
if (!isExpired && nextLatestAbsoluteTimeoutMs !== -1) {
// The tree was suspended.
const suspendedExpirationTime = expirationTime;
markSuspendedPriorityLevel(root, suspendedExpirationTime);
Expand Down Expand Up @@ -1567,7 +1566,6 @@ function retrySuspendedRoot(
fiber: Fiber,
suspendedTime: ExpirationTime,
) {
if (enableSuspense) {
let retryTime;

if (isPriorityLevelSuspended(root, suspendedTime)) {
Expand All @@ -1576,7 +1574,7 @@ function retrySuspendedRoot(

markPingedPriorityLevel(root, retryTime);
} else {
// Placeholder already timed out. Compute a new expiration time
// Suspense already timed out. Compute a new expiration time
const currentTime = requestCurrentTime();
retryTime = computeExpirationForFiber(currentTime, fiber);
markPendingPriorityLevel(root, retryTime);
Expand All @@ -1587,7 +1585,7 @@ function retrySuspendedRoot(
// we should not trigger another update here. One case this happens is when
// we are in sync mode and a single promise is thrown both on initial render
// and on update; we attach two .then(retrySuspendedRoot) callbacks and each
// one performs Sync work, rerendering the Placeholder.
// one performs Sync work, rerendering the Suspense.

if ((fiber.mode & ConcurrentMode) !== NoContext) {
if (root === nextRoot && nextRenderExpirationTime === suspendedTime) {
Expand All @@ -1603,7 +1601,6 @@ function retrySuspendedRoot(
requestWork(root, rootExpirationTime);
}
}
}

function scheduleWorkToRoot(fiber: Fiber, expirationTime): FiberRoot | null {
recordScheduleUpdate();
Expand Down Expand Up @@ -1877,7 +1874,7 @@ function onSuspend(
msUntilTimeout: number,
): void {
root.expirationTime = rootExpirationTime;
if (enableSuspense && msUntilTimeout === 0 && !shouldYield()) {
if (msUntilTimeout === 0 && !shouldYield()) {
// Don't wait an additional tick. Commit the tree immediately.
root.pendingCommitExpirationTime = suspendedExpirationTime;
root.finishedWork = finishedWork;
Expand All @@ -1895,7 +1892,6 @@ function onYield(root) {
}

function onTimeout(root, finishedWork, suspendedExpirationTime) {
if (enableSuspense) {
// The root timed out. Commit it.
root.pendingCommitExpirationTime = suspendedExpirationTime;
root.finishedWork = finishedWork;
Expand All @@ -1906,7 +1902,6 @@ function onTimeout(root, finishedWork, suspendedExpirationTime) {
currentSchedulerTime = currentRendererTime;
flushRoot(root, suspendedExpirationTime);
}
}

function onCommit(root, expirationTime) {
root.expirationTime = expirationTime;
Expand Down Expand Up @@ -2247,7 +2242,7 @@ function performWorkOnRoot(
// If this root previously suspended, clear its existing timeout, since
// we're about to try rendering again.
const timeoutHandle = root.timeoutHandle;
if (enableSuspense && timeoutHandle !== noTimeout) {
if (timeoutHandle !== noTimeout) {
root.timeoutHandle = noTimeout;
// $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
cancelTimeout(timeoutHandle);
Expand All @@ -2271,7 +2266,7 @@ function performWorkOnRoot(
// If this root previously suspended, clear its existing timeout, since
// we're about to try rendering again.
const timeoutHandle = root.timeoutHandle;
if (enableSuspense && timeoutHandle !== noTimeout) {
if (timeoutHandle !== noTimeout) {
root.timeoutHandle = noTimeout;
// $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
cancelTimeout(timeoutHandle);
Expand Down
Loading