Skip to content

Commit d2e914a

Browse files
authored
Remove remaining references to effect list (#19673)
* Remove `firstEffect` null check This is the last remaining place where the effect list has semantic implications. I've replaced it with a check of `effectTag` and `subtreeTag`, to see if there are any effects in the whole tree. This matches the semantics of the old check. However, I think only reason this optimization exists is because it affects profiling. We should reconsider whether this is necessary. * Remove remaining references to effect list We no longer use the effect list anywhere in our implementation. It's been replaced by a recursive traversal in the commit phase. This removes all references to the effect list in the new fork.
1 parent 0386bd0 commit d2e914a

9 files changed

+42
-206
lines changed

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

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -277,28 +277,13 @@ function ChildReconciler(shouldTrackSideEffects) {
277277
// Noop.
278278
return;
279279
}
280-
// Deletions are added in reversed order so we add it to the front.
281-
// At this point, the return fiber's effect list is empty except for
282-
// deletions, so we can just append the deletion to the list. The remaining
283-
// effects aren't added until the complete phase. Once we implement
284-
// resuming, this may not be true.
285-
// TODO (effects) Get rid of effects list update here.
286-
const last = returnFiber.lastEffect;
287-
if (last !== null) {
288-
last.nextEffect = childToDelete;
289-
returnFiber.lastEffect = childToDelete;
290-
} else {
291-
returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
292-
}
293280
const deletions = returnFiber.deletions;
294281
if (deletions === null) {
295282
returnFiber.deletions = [childToDelete];
296-
// TODO (effects) Rename this to better reflect its new usage (e.g. ChildDeletions)
297283
returnFiber.effectTag |= Deletion;
298284
} else {
299285
deletions.push(childToDelete);
300286
}
301-
childToDelete.nextEffect = null;
302287
}
303288

304289
function deleteRemainingChildren(

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

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,6 @@ function FiberNode(
147147
this.effectTag = NoEffect;
148148
this.subtreeTag = NoSubtreeEffect;
149149
this.deletions = null;
150-
this.nextEffect = null;
151-
152-
this.firstEffect = null;
153-
this.lastEffect = null;
154150

155151
this.lanes = NoLanes;
156152
this.childLanes = NoLanes;
@@ -291,11 +287,6 @@ export function createWorkInProgress(current: Fiber, pendingProps: any): Fiber {
291287
workInProgress.subtreeTag = NoSubtreeEffect;
292288
workInProgress.deletions = null;
293289

294-
// The effect list is no longer valid.
295-
workInProgress.nextEffect = null;
296-
workInProgress.firstEffect = null;
297-
workInProgress.lastEffect = null;
298-
299290
if (enableProfilerTimer) {
300291
// We intentionally reset, rather than copy, actualDuration & actualStartTime.
301292
// This prevents time from endlessly accumulating in new commits.
@@ -374,18 +365,14 @@ export function resetWorkInProgress(workInProgress: Fiber, renderLanes: Lanes) {
374365
// that child fiber is setting, not the reconciliation.
375366
workInProgress.effectTag &= Placement;
376367

377-
// The effect list is no longer valid.
378-
workInProgress.nextEffect = null;
379-
workInProgress.firstEffect = null;
380-
workInProgress.lastEffect = null;
381-
382368
const current = workInProgress.alternate;
383369
if (current === null) {
384370
// Reset to createFiber's initial values.
385371
workInProgress.childLanes = NoLanes;
386372
workInProgress.lanes = renderLanes;
387373

388374
workInProgress.child = null;
375+
workInProgress.subtreeTag = NoSubtreeEffect;
389376
workInProgress.memoizedProps = null;
390377
workInProgress.memoizedState = null;
391378
workInProgress.updateQueue = null;
@@ -406,6 +393,8 @@ export function resetWorkInProgress(workInProgress: Fiber, renderLanes: Lanes) {
406393
workInProgress.lanes = current.lanes;
407394

408395
workInProgress.child = current.child;
396+
workInProgress.subtreeTag = current.subtreeTag;
397+
workInProgress.deletions = null;
409398
workInProgress.memoizedProps = current.memoizedProps;
410399
workInProgress.memoizedState = current.memoizedState;
411400
workInProgress.updateQueue = current.updateQueue;
@@ -830,9 +819,6 @@ export function assignFiberPropertiesInDEV(
830819
target.effectTag = source.effectTag;
831820
target.subtreeTag = source.subtreeTag;
832821
target.deletions = source.deletions;
833-
target.nextEffect = source.nextEffect;
834-
target.firstEffect = source.firstEffect;
835-
target.lastEffect = source.lastEffect;
836822
target.lanes = source.lanes;
837823
target.childLanes = source.childLanes;
838824
target.alternate = source.alternate;

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

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2063,8 +2063,6 @@ function updateSuspensePrimaryChildren(
20632063
primaryChildFragment.sibling = null;
20642064
if (currentFallbackChildFragment !== null) {
20652065
// Delete the fallback child fragment
2066-
currentFallbackChildFragment.nextEffect = null;
2067-
workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment;
20682066
const deletions = workInProgress.deletions;
20692067
if (deletions === null) {
20702068
workInProgress.deletions = [currentFallbackChildFragment];
@@ -2129,21 +2127,8 @@ function updateSuspenseFallbackChildren(
21292127

21302128
// The fallback fiber was added as a deletion effect during the first pass.
21312129
// However, since we're going to remain on the fallback, we no longer want
2132-
// to delete it. So we need to remove it from the list. Deletions are stored
2133-
// on the same list as effects. We want to keep the effects from the primary
2134-
// tree. So we copy the primary child fragment's effect list, which does not
2135-
// include the fallback deletion effect.
2136-
const progressedLastEffect = primaryChildFragment.lastEffect;
2137-
if (progressedLastEffect !== null) {
2138-
workInProgress.firstEffect = primaryChildFragment.firstEffect;
2139-
workInProgress.lastEffect = progressedLastEffect;
2140-
progressedLastEffect.nextEffect = null;
2141-
workInProgress.deletions = null;
2142-
} else {
2143-
// TODO: Reset this somewhere else? Lol legacy mode is so weird.
2144-
workInProgress.firstEffect = workInProgress.lastEffect = null;
2145-
workInProgress.deletions = null;
2146-
}
2130+
// to delete it.
2131+
workInProgress.deletions = null;
21472132
} else {
21482133
primaryChildFragment = createWorkInProgressOffscreenFiber(
21492134
currentPrimaryChildFragment,
@@ -2633,7 +2618,6 @@ function initSuspenseListRenderState(
26332618
tail: null | Fiber,
26342619
lastContentRow: null | Fiber,
26352620
tailMode: SuspenseListTailMode,
2636-
lastEffectBeforeRendering: null | Fiber,
26372621
): void {
26382622
const renderState: null | SuspenseListRenderState =
26392623
workInProgress.memoizedState;
@@ -2645,7 +2629,6 @@ function initSuspenseListRenderState(
26452629
last: lastContentRow,
26462630
tail: tail,
26472631
tailMode: tailMode,
2648-
lastEffect: lastEffectBeforeRendering,
26492632
}: SuspenseListRenderState);
26502633
} else {
26512634
// We can reuse the existing object from previous renders.
@@ -2655,7 +2638,6 @@ function initSuspenseListRenderState(
26552638
renderState.last = lastContentRow;
26562639
renderState.tail = tail;
26572640
renderState.tailMode = tailMode;
2658-
renderState.lastEffect = lastEffectBeforeRendering;
26592641
}
26602642
}
26612643

@@ -2737,7 +2719,6 @@ function updateSuspenseListComponent(
27372719
tail,
27382720
lastContentRow,
27392721
tailMode,
2740-
workInProgress.lastEffect,
27412722
);
27422723
break;
27432724
}
@@ -2769,7 +2750,6 @@ function updateSuspenseListComponent(
27692750
tail,
27702751
null, // last
27712752
tailMode,
2772-
workInProgress.lastEffect,
27732753
);
27742754
break;
27752755
}
@@ -2780,7 +2760,6 @@ function updateSuspenseListComponent(
27802760
null, // tail
27812761
null, // last
27822762
undefined,
2783-
workInProgress.lastEffect,
27842763
);
27852764
break;
27862765
}
@@ -3040,13 +3019,6 @@ function remountFiber(
30403019

30413020
// Delete the old fiber and place the new one.
30423021
// Since the old fiber is disconnected, we have to schedule it manually.
3043-
const last = returnFiber.lastEffect;
3044-
if (last !== null) {
3045-
last.nextEffect = current;
3046-
returnFiber.lastEffect = current;
3047-
} else {
3048-
returnFiber.firstEffect = returnFiber.lastEffect = current;
3049-
}
30503022
const deletions = returnFiber.deletions;
30513023
if (deletions === null) {
30523024
returnFiber.deletions = [current];
@@ -3055,7 +3027,6 @@ function remountFiber(
30553027
} else {
30563028
deletions.push(current);
30573029
}
3058-
current.nextEffect = null;
30593030

30603031
newWorkInProgress.effectTag |= Placement;
30613032

@@ -3256,7 +3227,6 @@ function beginWork(
32563227
// update in the past but didn't complete it.
32573228
renderState.rendering = null;
32583229
renderState.tail = null;
3259-
renderState.lastEffect = null;
32603230
}
32613231
pushSuspenseContext(workInProgress, suspenseStackCursor.current);
32623232

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

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,18 +1049,8 @@ function completeWork(
10491049

10501050
// Rerender the whole list, but this time, we'll force fallbacks
10511051
// to stay in place.
1052-
// Reset the effect list before doing the second pass since that's now invalid.
1053-
if (renderState.lastEffect === null) {
1054-
workInProgress.firstEffect = null;
1055-
workInProgress.subtreeTag = NoEffect;
1056-
let child = workInProgress.child;
1057-
while (child !== null) {
1058-
child.deletions = null;
1059-
child = child.sibling;
1060-
}
1061-
}
1062-
workInProgress.lastEffect = renderState.lastEffect;
10631052
// Reset the child fibers to their original state.
1053+
workInProgress.subtreeTag = NoEffect;
10641054
resetChildFibers(workInProgress, renderLanes);
10651055

10661056
// Set up the Suspense Context to force suspense and immediately
@@ -1128,15 +1118,6 @@ function completeWork(
11281118
!renderedTail.alternate &&
11291119
!getIsHydrating() // We don't cut it if we're hydrating.
11301120
) {
1131-
// We need to delete the row we just rendered.
1132-
// Reset the effect list to what it was before we rendered this
1133-
// child. The nested children have already appended themselves.
1134-
const lastEffect = (workInProgress.lastEffect =
1135-
renderState.lastEffect);
1136-
// Remove any effects that were appended after this point.
1137-
if (lastEffect !== null) {
1138-
lastEffect.nextEffect = null;
1139-
}
11401121
// We're done.
11411122
return null;
11421123
}
@@ -1192,7 +1173,6 @@ function completeWork(
11921173
const next = renderState.tail;
11931174
renderState.rendering = next;
11941175
renderState.tail = next.sibling;
1195-
renderState.lastEffect = workInProgress.lastEffect;
11961176
renderState.renderingStartTime = now();
11971177
next.sibling = null;
11981178

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -133,18 +133,6 @@ function deleteHydratableInstance(
133133
} else {
134134
deletions.push(childToDelete);
135135
}
136-
137-
// This might seem like it belongs on progressedFirstDeletion. However,
138-
// these children are not part of the reconciliation list of children.
139-
// Even if we abort and rereconcile the children, that will try to hydrate
140-
// again and the nodes are still in the host tree so these will be
141-
// recreated.
142-
if (returnFiber.lastEffect !== null) {
143-
returnFiber.lastEffect.nextEffect = childToDelete;
144-
returnFiber.lastEffect = childToDelete;
145-
} else {
146-
returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
147-
}
148136
}
149137

150138
function insertNonHydratedInstance(returnFiber: Fiber, fiber: Fiber) {

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@ export type SuspenseListRenderState = {|
4949
tail: null | Fiber,
5050
// Tail insertions setting.
5151
tailMode: SuspenseListTailMode,
52-
// Last Effect before we rendered the "rendering" item.
53-
// Used to remove new effects added by the rendered item.
54-
lastEffect: null | Fiber,
5552
|};
5653

5754
export function shouldCaptureSuspense(

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,6 @@ function throwException(
185185
) {
186186
// The source fiber did not complete.
187187
sourceFiber.effectTag |= Incomplete;
188-
// Its effect list is no longer valid.
189-
sourceFiber.firstEffect = sourceFiber.lastEffect = null;
190188

191189
if (
192190
value !== null &&

0 commit comments

Comments
 (0)