Skip to content

Commit fceb75e

Browse files
authoredJan 20, 2021
Delete remaining references to effect list (#20625)
I think that's it!
1 parent 741dcbd commit fceb75e

10 files changed

+63
-167
lines changed
 

‎.eslintrc.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ module.exports = {
116116
'react-internal/no-cross-fork-types': [
117117
ERROR,
118118
{
119-
old: [],
119+
old: ['firstEffect', 'nextEffect'],
120120
new: [],
121121
},
122122
],

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

-14
Original file line numberDiff line numberDiff line change
@@ -263,20 +263,6 @@ function ChildReconciler(shouldTrackSideEffects) {
263263
// Noop.
264264
return;
265265
}
266-
// Deletions are added in reversed order so we add it to the front.
267-
// At this point, the return fiber's effect list is empty except for
268-
// deletions, so we can just append the deletion to the list. The remaining
269-
// effects aren't added until the complete phase. Once we implement
270-
// resuming, this may not be true.
271-
const last = returnFiber.lastEffect;
272-
if (last !== null) {
273-
last.nextEffect = childToDelete;
274-
returnFiber.lastEffect = childToDelete;
275-
} else {
276-
returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
277-
}
278-
childToDelete.nextEffect = null;
279-
280266
const deletions = returnFiber.deletions;
281267
if (deletions === null) {
282268
returnFiber.deletions = [childToDelete];

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

+5-15
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,6 @@ function FiberNode(
144144

145145
// Effects
146146
this.flags = NoFlags;
147-
this.nextEffect = null;
148-
149-
this.firstEffect = null;
150-
this.lastEffect = null;
151147
this.subtreeFlags = NoFlags;
152148
this.deletions = null;
153149

@@ -285,10 +281,7 @@ export function createWorkInProgress(current: Fiber, pendingProps: any): Fiber {
285281
// Reset the effect tag.
286282
workInProgress.flags = NoFlags;
287283

288-
// The effect list is no longer valid.
289-
workInProgress.nextEffect = null;
290-
workInProgress.firstEffect = null;
291-
workInProgress.lastEffect = null;
284+
// The effects are no longer valid.
292285
workInProgress.subtreeFlags = NoFlags;
293286
workInProgress.deletions = null;
294287

@@ -370,10 +363,7 @@ export function resetWorkInProgress(workInProgress: Fiber, renderLanes: Lanes) {
370363
// that child fiber is setting, not the reconciliation.
371364
workInProgress.flags &= StaticMask | Placement;
372365

373-
// The effect list is no longer valid.
374-
workInProgress.nextEffect = null;
375-
workInProgress.firstEffect = null;
376-
workInProgress.lastEffect = null;
366+
// The effects are no longer valid.
377367

378368
const current = workInProgress.alternate;
379369
if (current === null) {
@@ -403,6 +393,9 @@ export function resetWorkInProgress(workInProgress: Fiber, renderLanes: Lanes) {
403393
workInProgress.lanes = current.lanes;
404394

405395
workInProgress.child = current.child;
396+
// TODO: `subtreeFlags` should be reset to NoFlags, like we do in
397+
// `createWorkInProgress`. Nothing reads this until the complete phase,
398+
// currently, but it might in the future, and we should be consistent.
406399
workInProgress.subtreeFlags = current.subtreeFlags;
407400
workInProgress.deletions = null;
408401
workInProgress.memoizedProps = current.memoizedProps;
@@ -847,9 +840,6 @@ export function assignFiberPropertiesInDEV(
847840
target.dependencies = source.dependencies;
848841
target.mode = source.mode;
849842
target.flags = source.flags;
850-
target.nextEffect = source.nextEffect;
851-
target.firstEffect = source.firstEffect;
852-
target.lastEffect = source.lastEffect;
853843
target.subtreeFlags = source.subtreeFlags;
854844
target.deletions = source.deletions;
855845
target.lanes = source.lanes;

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

+3-33
Original file line numberDiff line numberDiff line change
@@ -2198,8 +2198,6 @@ function updateSuspensePrimaryChildren(
21982198
primaryChildFragment.sibling = null;
21992199
if (currentFallbackChildFragment !== null) {
22002200
// Delete the fallback child fragment
2201-
currentFallbackChildFragment.nextEffect = null;
2202-
workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment;
22032201
const deletions = workInProgress.deletions;
22042202
if (deletions === null) {
22052203
workInProgress.deletions = [currentFallbackChildFragment];
@@ -2261,22 +2259,9 @@ function updateSuspenseFallbackChildren(
22612259
currentPrimaryChildFragment.treeBaseDuration;
22622260
}
22632261

2264-
if (currentFallbackChildFragment !== null) {
2265-
// The fallback fiber was added as a deletion effect during the first
2266-
// pass. However, since we're going to remain on the fallback, we no
2267-
// longer want to delete it. So we need to remove it from the list.
2268-
// Deletions are stored on the same list as effects, and are always added
2269-
// to the front. So we know that the first effect must be the fallback
2270-
// deletion effect, and everything after that is from the primary free.
2271-
const firstPrimaryTreeEffect = currentFallbackChildFragment.nextEffect;
2272-
if (firstPrimaryTreeEffect !== null) {
2273-
workInProgress.firstEffect = firstPrimaryTreeEffect;
2274-
} else {
2275-
// TODO: Reset this somewhere else? Lol legacy mode is so weird.
2276-
workInProgress.firstEffect = workInProgress.lastEffect = null;
2277-
}
2278-
}
2279-
2262+
// The fallback fiber was added as a deletion during the first pass.
2263+
// However, since we're going to remain on the fallback, we no longer want
2264+
// to delete it.
22802265
workInProgress.deletions = null;
22812266
} else {
22822267
primaryChildFragment = createWorkInProgressOffscreenFiber(
@@ -2773,7 +2758,6 @@ function initSuspenseListRenderState(
27732758
tail: null | Fiber,
27742759
lastContentRow: null | Fiber,
27752760
tailMode: SuspenseListTailMode,
2776-
lastEffectBeforeRendering: null | Fiber,
27772761
): void {
27782762
const renderState: null | SuspenseListRenderState =
27792763
workInProgress.memoizedState;
@@ -2785,7 +2769,6 @@ function initSuspenseListRenderState(
27852769
last: lastContentRow,
27862770
tail: tail,
27872771
tailMode: tailMode,
2788-
lastEffect: lastEffectBeforeRendering,
27892772
}: SuspenseListRenderState);
27902773
} else {
27912774
// We can reuse the existing object from previous renders.
@@ -2795,7 +2778,6 @@ function initSuspenseListRenderState(
27952778
renderState.last = lastContentRow;
27962779
renderState.tail = tail;
27972780
renderState.tailMode = tailMode;
2798-
renderState.lastEffect = lastEffectBeforeRendering;
27992781
}
28002782
}
28012783

@@ -2877,7 +2859,6 @@ function updateSuspenseListComponent(
28772859
tail,
28782860
lastContentRow,
28792861
tailMode,
2880-
workInProgress.lastEffect,
28812862
);
28822863
break;
28832864
}
@@ -2909,7 +2890,6 @@ function updateSuspenseListComponent(
29092890
tail,
29102891
null, // last
29112892
tailMode,
2912-
workInProgress.lastEffect,
29132893
);
29142894
break;
29152895
}
@@ -2920,7 +2900,6 @@ function updateSuspenseListComponent(
29202900
null, // tail
29212901
null, // last
29222902
undefined,
2923-
workInProgress.lastEffect,
29242903
);
29252904
break;
29262905
}
@@ -3180,15 +3159,6 @@ function remountFiber(
31803159

31813160
// Delete the old fiber and place the new one.
31823161
// Since the old fiber is disconnected, we have to schedule it manually.
3183-
const last = returnFiber.lastEffect;
3184-
if (last !== null) {
3185-
last.nextEffect = current;
3186-
returnFiber.lastEffect = current;
3187-
} else {
3188-
returnFiber.firstEffect = returnFiber.lastEffect = current;
3189-
}
3190-
current.nextEffect = null;
3191-
31923162
const deletions = returnFiber.deletions;
31933163
if (deletions === null) {
31943164
returnFiber.deletions = [current];

‎packages/react-reconciler/src/ReactFiberCommitWork.new.js

-3
Original file line numberDiff line numberDiff line change
@@ -1213,9 +1213,6 @@ export function detachFiberAfterEffects(fiber: Fiber): void {
12131213
fiber.sibling = null;
12141214
fiber.stateNode = null;
12151215
fiber.updateQueue = null;
1216-
fiber.nextEffect = null;
1217-
fiber.firstEffect = null;
1218-
fiber.lastEffect = null;
12191216

12201217
if (__DEV__) {
12211218
fiber._debugOwner = null;

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

+35-22
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ import {
7272
NoFlags,
7373
DidCapture,
7474
Snapshot,
75+
ChildDeletion,
7576
StaticMask,
77+
MutationMask,
7678
} from './ReactFiberFlags';
7779
import invariant from 'shared/invariant';
7880

@@ -173,6 +175,31 @@ function markRef(workInProgress: Fiber) {
173175
workInProgress.flags |= Ref;
174176
}
175177

178+
function hadNoMutationsEffects(current: null | Fiber, completedWork: Fiber) {
179+
const didBailout = current !== null && current.child === completedWork.child;
180+
if (didBailout) {
181+
return true;
182+
}
183+
184+
if ((completedWork.flags & ChildDeletion) !== NoFlags) {
185+
return false;
186+
}
187+
188+
// TODO: If we move the `hadNoMutationsEffects` call after `bubbleProperties`
189+
// then we only have to check the `completedWork.subtreeFlags`.
190+
let child = completedWork.child;
191+
while (child !== null) {
192+
if (
193+
(child.flags & MutationMask) !== NoFlags ||
194+
(child.subtreeFlags & MutationMask) !== NoFlags
195+
) {
196+
return false;
197+
}
198+
child = child.sibling;
199+
}
200+
return true;
201+
}
202+
176203
let appendAllChildren;
177204
let updateHostContainer;
178205
let updateHostComponent;
@@ -217,7 +244,7 @@ if (supportsMutation) {
217244
}
218245
};
219246

220-
updateHostContainer = function(workInProgress: Fiber) {
247+
updateHostContainer = function(current: null | Fiber, workInProgress: Fiber) {
221248
// Noop
222249
};
223250
updateHostComponent = function(
@@ -461,13 +488,13 @@ if (supportsMutation) {
461488
node = node.sibling;
462489
}
463490
};
464-
updateHostContainer = function(workInProgress: Fiber) {
491+
updateHostContainer = function(current: null | Fiber, workInProgress: Fiber) {
465492
const portalOrRoot: {
466493
containerInfo: Container,
467494
pendingChildren: ChildSet,
468495
...
469496
} = workInProgress.stateNode;
470-
const childrenUnchanged = workInProgress.firstEffect === null;
497+
const childrenUnchanged = hadNoMutationsEffects(current, workInProgress);
471498
if (childrenUnchanged) {
472499
// No changes, just reuse the existing instance.
473500
} else {
@@ -492,7 +519,7 @@ if (supportsMutation) {
492519
const oldProps = current.memoizedProps;
493520
// If there are no effects associated with this node, then none of our children had any updates.
494521
// This guarantees that we can reuse all of them.
495-
const childrenUnchanged = workInProgress.firstEffect === null;
522+
const childrenUnchanged = hadNoMutationsEffects(current, workInProgress);
496523
if (childrenUnchanged && oldProps === newProps) {
497524
// No changes, just reuse the existing instance.
498525
// Note that this might release a previous clone.
@@ -575,7 +602,7 @@ if (supportsMutation) {
575602
};
576603
} else {
577604
// No host operations
578-
updateHostContainer = function(workInProgress: Fiber) {
605+
updateHostContainer = function(current: null | Fiber, workInProgress: Fiber) {
579606
// Noop
580607
};
581608
updateHostComponent = function(
@@ -847,7 +874,7 @@ function completeWork(
847874
workInProgress.flags |= Snapshot;
848875
}
849876
}
850-
updateHostContainer(workInProgress);
877+
updateHostContainer(current, workInProgress);
851878
bubbleProperties(workInProgress);
852879
return null;
853880
}
@@ -1142,7 +1169,7 @@ function completeWork(
11421169
}
11431170
case HostPortal:
11441171
popHostContainer(workInProgress);
1145-
updateHostContainer(workInProgress);
1172+
updateHostContainer(current, workInProgress);
11461173
if (current === null) {
11471174
preparePortalMount(workInProgress.stateNode.containerInfo);
11481175
}
@@ -1226,11 +1253,7 @@ function completeWork(
12261253

12271254
// Rerender the whole list, but this time, we'll force fallbacks
12281255
// to stay in place.
1229-
// Reset the effect list before doing the second pass since that's now invalid.
1230-
if (renderState.lastEffect === null) {
1231-
workInProgress.firstEffect = null;
1232-
}
1233-
workInProgress.lastEffect = renderState.lastEffect;
1256+
// Reset the effect flags before doing the second pass since that's now invalid.
12341257
// Reset the child fibers to their original state.
12351258
workInProgress.subtreeFlags = NoFlags;
12361259
resetChildFibers(workInProgress, renderLanes);
@@ -1301,15 +1324,6 @@ function completeWork(
13011324
!renderedTail.alternate &&
13021325
!getIsHydrating() // We don't cut it if we're hydrating.
13031326
) {
1304-
// We need to delete the row we just rendered.
1305-
// Reset the effect list to what it was before we rendered this
1306-
// child. The nested children have already appended themselves.
1307-
const lastEffect = (workInProgress.lastEffect =
1308-
renderState.lastEffect);
1309-
// Remove any effects that were appended after this point.
1310-
if (lastEffect !== null) {
1311-
lastEffect.nextEffect = null;
1312-
}
13131327
// We're done.
13141328
bubbleProperties(workInProgress);
13151329
return null;
@@ -1369,7 +1383,6 @@ function completeWork(
13691383
const next = renderState.tail;
13701384
renderState.rendering = next;
13711385
renderState.tail = next.sibling;
1372-
renderState.lastEffect = workInProgress.lastEffect;
13731386
renderState.renderingStartTime = now();
13741387
next.sibling = null;
13751388

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

-12
Original file line numberDiff line numberDiff line change
@@ -125,18 +125,6 @@ function deleteHydratableInstance(
125125
childToDelete.stateNode = instance;
126126
childToDelete.return = returnFiber;
127127

128-
// This might seem like it belongs on progressedFirstDeletion. However,
129-
// these children are not part of the reconciliation list of children.
130-
// Even if we abort and rereconcile the children, that will try to hydrate
131-
// again and the nodes are still in the host tree so these will be
132-
// recreated.
133-
if (returnFiber.lastEffect !== null) {
134-
returnFiber.lastEffect.nextEffect = childToDelete;
135-
returnFiber.lastEffect = childToDelete;
136-
} else {
137-
returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
138-
}
139-
140128
const deletions = returnFiber.deletions;
141129
if (deletions === null) {
142130
returnFiber.deletions = [childToDelete];

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

-3
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@ export type SuspenseListRenderState = {|
6060
tail: null | Fiber,
6161
// Tail insertions setting.
6262
tailMode: SuspenseListTailMode,
63-
// Last Effect before we rendered the "rendering" item.
64-
// Used to remove new effects added by the rendered item.
65-
lastEffect: null | Fiber,
6663
|};
6764

6865
export function shouldCaptureSuspense(

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

-2
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,6 @@ function throwException(
188188
) {
189189
// The source fiber did not complete.
190190
sourceFiber.flags |= Incomplete;
191-
// Its effect list is no longer valid.
192-
sourceFiber.firstEffect = sourceFiber.lastEffect = null;
193191

194192
if (
195193
value !== null &&

0 commit comments

Comments
 (0)