Skip to content

Commit

Permalink
Retrying a dehydrated boundary pings at the earliest forced time
Browse files Browse the repository at this point in the history
This might quickly become an already expired time.
  • Loading branch information
sebmarkbage committed Aug 12, 2019
1 parent f6105b5 commit 6920889
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
4 changes: 2 additions & 2 deletions packages/react-reconciler/src/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ import {
import {
markSpawnedWork,
requestCurrentTime,
retryTimedOutBoundary,
retryDehydratedSuspenseBoundary,
scheduleWork,
} from './ReactFiberWorkLoop';

Expand Down Expand Up @@ -2081,7 +2081,7 @@ function updateDehydratedSuspenseComponent(
// Register a callback to retry this boundary once the server has sent the result.
registerSuspenseInstanceRetry(
suspenseInstance,
retryTimedOutBoundary.bind(null, current),
retryDehydratedSuspenseBoundary.bind(null, current),
);
return null;
} else {
Expand Down
36 changes: 28 additions & 8 deletions packages/react-reconciler/src/ReactFiberWorkLoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
} from './SchedulerWithReactIntegration';
import type {Interaction} from 'scheduler/src/Tracing';
import type {SuspenseConfig} from './ReactFiberSuspenseConfig';
import type {SuspenseState} from './ReactFiberSuspenseComponent';

import {
warnAboutDeprecatedLifecycles,
Expand Down Expand Up @@ -2180,18 +2181,23 @@ export function pingSuspendedRoot(
scheduleCallbackForRoot(root, priorityLevel, suspendedTime);
}

export function retryTimedOutBoundary(boundaryFiber: Fiber) {
function retryTimedOutBoundary(
boundaryFiber: Fiber,
retryTime: ExpirationTime,
) {
// The boundary fiber (a Suspense component or SuspenseList component)
// previously was rendered in its fallback state. One of the promises that
// suspended it has resolved, which means at least part of the tree was
// likely unblocked. Try rendering again, at a new expiration time.
const currentTime = requestCurrentTime();
const suspenseConfig = null; // Retries don't carry over the already committed update.
const retryTime = computeExpirationForFiber(
currentTime,
boundaryFiber,
suspenseConfig,
);
if (retryTime === Never) {
const suspenseConfig = null; // Retries don't carry over the already committed update.
retryTime = computeExpirationForFiber(
currentTime,
boundaryFiber,
suspenseConfig,
);
}
// TODO: Special case idle priority?
const priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime);
const root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
Expand All @@ -2200,12 +2206,26 @@ export function retryTimedOutBoundary(boundaryFiber: Fiber) {
}
}

export function retryDehydratedSuspenseBoundary(boundaryFiber: Fiber) {
const suspenseState: null | SuspenseState = boundaryFiber.memoizedState;
let retryTime = Never;
if (suspenseState !== null) {
retryTime = suspenseState.retryTime;
}
retryTimedOutBoundary(boundaryFiber, retryTime);
}

export function resolveRetryThenable(boundaryFiber: Fiber, thenable: Thenable) {
let retryTime = Never; // Default
let retryCache: WeakSet<Thenable> | Set<Thenable> | null;
if (enableSuspenseServerRenderer) {
switch (boundaryFiber.tag) {
case SuspenseComponent:
retryCache = boundaryFiber.stateNode;
const suspenseState: null | SuspenseState = boundaryFiber.memoizedState;
if (suspenseState !== null) {
retryTime = suspenseState.retryTime;
}
break;
default:
invariant(
Expand All @@ -2224,7 +2244,7 @@ export function resolveRetryThenable(boundaryFiber: Fiber, thenable: Thenable) {
retryCache.delete(thenable);
}

retryTimedOutBoundary(boundaryFiber);
retryTimedOutBoundary(boundaryFiber, retryTime);
}

// Computes the next Just Noticeable Difference (JND) boundary.
Expand Down

0 comments on commit 6920889

Please sign in to comment.