Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 8 additions & 32 deletions packages/react-reconciler/src/ReactChildFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type {Fiber} from 'react-reconciler/src/ReactFiber';
import type {ExpirationTime} from 'react-reconciler/src/ReactFiberExpirationTime';

import {enableReactFragment} from 'shared/ReactFeatureFlags';
import {NoEffect, Placement, Deletion} from 'shared/ReactTypeOfSideEffect';
import {Placement, Deletion} from 'shared/ReactTypeOfSideEffect';
import {
FunctionalComponent,
ClassComponent,
Expand Down Expand Up @@ -222,21 +222,12 @@ function warnOnFunctionType() {
// to be able to optimize each path individually by branching early. This needs
// a compiler or we can do it manually. Helpers that don't need this branching
// live outside of this function.
function ChildReconciler(shouldClone, shouldTrackSideEffects) {
function ChildReconciler(shouldTrackSideEffects) {
function deleteChild(returnFiber: Fiber, childToDelete: Fiber): void {
if (!shouldTrackSideEffects) {
// Noop.
return;
}
if (!shouldClone) {
// When we're reconciling in place we have a work in progress copy. We
// actually want the current copy. If there is no current copy, then we
// don't need to track deletion side-effects.
if (childToDelete.alternate === null) {
return;
}
childToDelete = childToDelete.alternate;
}
// Deletions are added in reversed order so we add it to the front.
// At this point, the return fiber's effect list is empty except for
// deletions, so we can just append the deletion to the list. The remaining
Expand Down Expand Up @@ -300,22 +291,10 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
): Fiber {
// We currently set sibling to null and index to 0 here because it is easy
// to forget to do before returning it. E.g. for the single child case.
if (shouldClone) {
const clone = createWorkInProgress(fiber, pendingProps, expirationTime);
clone.index = 0;
clone.sibling = null;
return clone;
} else {
// We override the expiration time even if it is earlier, because if
// we're reconciling at a later time that means that this was
// down-prioritized.
fiber.expirationTime = expirationTime;
fiber.effectTag = NoEffect;
fiber.index = 0;
fiber.sibling = null;
fiber.pendingProps = pendingProps;
return fiber;
}
const clone = createWorkInProgress(fiber, pendingProps, expirationTime);
clone.index = 0;
clone.sibling = null;
return clone;
}

function placeChild(
Expand Down Expand Up @@ -1553,11 +1532,8 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
return reconcileChildFibers;
}

export const reconcileChildFibers = ChildReconciler(true, true);

export const reconcileChildFibersInPlace = ChildReconciler(false, true);

export const mountChildFibersInPlace = ChildReconciler(false, false);
export const reconcileChildFibers = ChildReconciler(true);
export const mountChildFibers = ChildReconciler(false);

export function cloneChildFibers(
current: Fiber | null,
Expand Down
40 changes: 11 additions & 29 deletions packages/react-reconciler/src/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,8 @@ import {cancelWorkTimer} from './ReactDebugFiberPerf';

import ReactFiberClassComponent from './ReactFiberClassComponent';
import {
mountChildFibersInPlace,
mountChildFibers,
reconcileChildFibers,
reconcileChildFibersInPlace,
cloneChildFibers,
} from './ReactChildFiber';
import {processUpdateQueue} from './ReactFiberUpdateQueue';
Expand Down Expand Up @@ -119,13 +118,13 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
// won't update its child set by applying minimal side-effects. Instead,
// we will add them all to the child before it gets rendered. That means
// we can optimize this reconciliation pass by not tracking side-effects.
workInProgress.child = mountChildFibersInPlace(
workInProgress.child = mountChildFibers(
workInProgress,
workInProgress.child,
null,
nextChildren,
renderExpirationTime,
);
} else if (current.child === workInProgress.child) {
} else {
// If the current child is the same as the work in progress, it means that
// we haven't yet started any work on these children. Therefore, we use
// the clone algorithm to create a copy of all the current children.
Expand All @@ -134,17 +133,7 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
// let's throw it out.
workInProgress.child = reconcileChildFibers(
workInProgress,
workInProgress.child,
nextChildren,
renderExpirationTime,
);
} else {
// If, on the other hand, it is already using a clone, that means we've
// already begun some work on this tree and we can continue where we left
// off by reconciling against the existing children.
workInProgress.child = reconcileChildFibersInPlace(
workInProgress,
workInProgress.child,
current.child,
nextChildren,
renderExpirationTime,
);
Expand Down Expand Up @@ -355,9 +344,9 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
// Ensure that children mount into this root without tracking
// side-effects. This ensures that we don't store Placement effects on
// nodes that will be hydrated.
workInProgress.child = mountChildFibersInPlace(
workInProgress.child = mountChildFibers(
workInProgress,
workInProgress.child,
null,
element,
renderExpirationTime,
);
Expand Down Expand Up @@ -569,21 +558,14 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
// The following is a fork of reconcileChildrenAtExpirationTime but using
// stateNode to store the child.
if (current === null) {
workInProgress.stateNode = mountChildFibersInPlace(
workInProgress,
workInProgress.stateNode,
nextChildren,
renderExpirationTime,
);
} else if (current.child === workInProgress.child) {
workInProgress.stateNode = reconcileChildFibers(
workInProgress.stateNode = mountChildFibers(
workInProgress,
workInProgress.stateNode,
nextChildren,
renderExpirationTime,
);
} else {
workInProgress.stateNode = reconcileChildFibersInPlace(
workInProgress.stateNode = reconcileChildFibers(
workInProgress,
workInProgress.stateNode,
nextChildren,
Expand Down Expand Up @@ -628,9 +610,9 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
// flow doesn't do during mount. This doesn't happen at the root because
// the root always starts with a "current" with a null child.
// TODO: Consider unifying this with how the root works.
workInProgress.child = reconcileChildFibersInPlace(
workInProgress.child = reconcileChildFibers(
workInProgress,
workInProgress.child,
null,
nextChildren,
renderExpirationTime,
);
Expand Down