Skip to content

Commit 9e4b112

Browse files
committed
Don't treat "retries" as a regular update
A "retry" is not a regular kind of update. It cannot unblock a suspended tree because it contains no additional data on its own. All it does is tell a Suspense boundary to attempt to switch back to its regular state. This distinction will be important in a new feature I'm working on, so instead of calling `markRootUpdated` during a retry, I refactored it to call a different function instead.
1 parent 1a70d38 commit 9e4b112

File tree

4 files changed

+36
-6
lines changed

4 files changed

+36
-6
lines changed

packages/react-reconciler/src/ReactFiberLane.new.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ export function createLaneMap<T>(initial: T): LaneMap<T> {
584584
return laneMap;
585585
}
586586

587-
export function markRootUpdated(
587+
export function markRootHasPendingWork(
588588
root: FiberRoot,
589589
updateLane: Lane,
590590
eventTime: number,

packages/react-reconciler/src/ReactFiberLane.old.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ export function createLaneMap<T>(initial: T): LaneMap<T> {
584584
return laneMap;
585585
}
586586

587-
export function markRootUpdated(
587+
export function markRootHasPendingWork(
588588
root: FiberRoot,
589589
updateLane: Lane,
590590
eventTime: number,

packages/react-reconciler/src/ReactFiberWorkLoop.new.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ import {
153153
markStarvedLanesAsExpired,
154154
getLanesToRetrySynchronouslyOnError,
155155
getMostRecentEventTime,
156-
markRootUpdated,
156+
markRootHasPendingWork,
157157
markRootSuspended as markRootSuspended_dontCallThisOneDirectly,
158158
markRootPinged,
159159
markRootEntangled,
@@ -813,6 +813,16 @@ export function scheduleUpdateOnFiber(
813813
}
814814
}
815815

816+
function markRootUpdated(root: FiberRoot, lanes: Lanes, eventTime: number) {
817+
// This function should be called whenever a root receives an update that
818+
// contains new information.
819+
//
820+
// Notably, this excludes "retries" — when a promise resolves and we schedule
821+
// work to flip a Suspense boundary from a fallback back to its regular state.
822+
// A retry cannot unblock existing work,
823+
markRootHasPendingWork(root, lanes, eventTime);
824+
}
825+
816826
export function scheduleInitialHydrationOnRoot(
817827
root: FiberRoot,
818828
lane: Lane,
@@ -3187,7 +3197,12 @@ function retryTimedOutBoundary(boundaryFiber: Fiber, retryLane: Lane) {
31873197
const eventTime = requestEventTime();
31883198
const root = enqueueConcurrentRenderForLane(boundaryFiber, retryLane);
31893199
if (root !== null) {
3190-
markRootUpdated(root, retryLane, eventTime);
3200+
// A "retry" is not a regular kind of update. It cannot unblock a suspended
3201+
// tree because it contains no additional data on its own. All it does is
3202+
// tell a Suspense boundary to attempt to switch back to its regular state.
3203+
//
3204+
// So we call markRootHasPendingWork here instead of markRootUpdated.
3205+
markRootHasPendingWork(root, retryLane, eventTime);
31913206
ensureRootIsScheduled(root, eventTime);
31923207
}
31933208
}

packages/react-reconciler/src/ReactFiberWorkLoop.old.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ import {
153153
markStarvedLanesAsExpired,
154154
getLanesToRetrySynchronouslyOnError,
155155
getMostRecentEventTime,
156-
markRootUpdated,
156+
markRootHasPendingWork,
157157
markRootSuspended as markRootSuspended_dontCallThisOneDirectly,
158158
markRootPinged,
159159
markRootEntangled,
@@ -813,6 +813,16 @@ export function scheduleUpdateOnFiber(
813813
}
814814
}
815815

816+
function markRootUpdated(root: FiberRoot, lanes: Lanes, eventTime: number) {
817+
// This function should be called whenever a root receives an update that
818+
// contains new information.
819+
//
820+
// Notably, this excludes "retries" — when a promise resolves and we schedule
821+
// work to flip a Suspense boundary from a fallback back to its regular state.
822+
// A retry cannot unblock existing work,
823+
markRootHasPendingWork(root, lanes, eventTime);
824+
}
825+
816826
export function scheduleInitialHydrationOnRoot(
817827
root: FiberRoot,
818828
lane: Lane,
@@ -3187,7 +3197,12 @@ function retryTimedOutBoundary(boundaryFiber: Fiber, retryLane: Lane) {
31873197
const eventTime = requestEventTime();
31883198
const root = enqueueConcurrentRenderForLane(boundaryFiber, retryLane);
31893199
if (root !== null) {
3190-
markRootUpdated(root, retryLane, eventTime);
3200+
// A "retry" is not a regular kind of update. It cannot unblock a suspended
3201+
// tree because it contains no additional data on its own. All it does is
3202+
// tell a Suspense boundary to attempt to switch back to its regular state.
3203+
//
3204+
// So we call markRootHasPendingWork here instead of markRootUpdated.
3205+
markRootHasPendingWork(root, retryLane, eventTime);
31913206
ensureRootIsScheduled(root, eventTime);
31923207
}
31933208
}

0 commit comments

Comments
 (0)