Skip to content

Commit 3b5c917

Browse files
committed
Exclude hydration from nested update check
If a commit was the result of selective hydration, we should not increment the nested update count, because those renders conceptually are not updates. Ideally, they wouldn't even be in a separate commit — we should be able to hydrate a tree and apply an update on top of it within the same render phase. We could do this once we implement resumable context stacks.
1 parent 029d43f commit 3b5c917

2 files changed

Lines changed: 15 additions & 2 deletions

File tree

packages/react-reconciler/src/ReactFiberLane.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ export const InputContinuousLane: Lane = /* */ 0b0000000000000000000
4646
export const DefaultHydrationLane: Lane = /* */ 0b0000000000000000000000000010000;
4747
export const DefaultLane: Lane = /* */ 0b0000000000000000000000000100000;
4848

49-
export const SyncUpdateLanes: Lane = /* */ 0b0000000000000000000000000101010;
49+
export const SyncUpdateLanes: Lane = enableUnifiedSyncLane
50+
? SyncLane | InputContinuousLane | DefaultLane
51+
: SyncLane;
5052

5153
const TransitionHydrationLane: Lane = /* */ 0b0000000000000000000000001000000;
5254
const TransitionLanes: Lanes = /* */ 0b0000000011111111111111110000000;

packages/react-reconciler/src/ReactFiberWorkLoop.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ import {
154154
includesOnlyNonUrgentLanes,
155155
includesSomeLane,
156156
OffscreenLane,
157+
SyncUpdateLanes,
157158
} from './ReactFiberLane';
158159
import {
159160
DiscreteEventPriority,
@@ -2932,7 +2933,17 @@ function commitRootImpl(
29322933

29332934
// Read this again, since a passive effect might have updated it
29342935
remainingLanes = root.pendingLanes;
2935-
if (includesSyncLane(remainingLanes)) {
2936+
2937+
// Check if this render scheduled a cascading synchronous update. This is a
2938+
// heurstic to detect infinite update loops. We are intentionally excluding
2939+
// hydration lanes in this check, because render triggered by selective
2940+
// hydration is conceptually not an update.
2941+
if (
2942+
// Was the finished render the result of a sync update?
2943+
includesSomeLane(lanes, SyncUpdateLanes) &&
2944+
// Did is schedule another sync update?
2945+
includesSomeLane(remainingLanes, SyncUpdateLanes)
2946+
) {
29362947
if (enableProfilerTimer && enableProfilerNestedUpdatePhase) {
29372948
markNestedUpdateScheduled();
29382949
}

0 commit comments

Comments
 (0)