Skip to content
Merged
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
35 changes: 28 additions & 7 deletions packages/react-reconciler/src/ReactFiberCompleteWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ import {
NoEffect,
DidCapture,
Snapshot,
MutationMask,
} from './ReactSideEffectTags';
import {NoEffect as NoSubtreeTag, Mutation} from './ReactSubtreeTags';
import invariant from 'shared/invariant';

import {
Expand Down Expand Up @@ -154,6 +156,25 @@ function markRef(workInProgress: Fiber) {
workInProgress.effectTag |= Ref;
}

function hadNoMutationsEffects(current: null | Fiber, completedWork: Fiber) {
const didBailout = current !== null && current.child === completedWork.child;
if (didBailout) {
return true;
}

let child = completedWork.child;
while (child !== null) {
if ((child.effectTag & MutationMask) !== NoEffect) {
return false;
}
if ((child.subtreeTag & Mutation) !== NoSubtreeTag) {
return false;
}
child = child.sibling;
}
return true;
}

let appendAllChildren;
let updateHostContainer;
let updateHostComponent;
Expand Down Expand Up @@ -198,7 +219,7 @@ if (supportsMutation) {
}
};

updateHostContainer = function(workInProgress: Fiber) {
updateHostContainer = function(current: null | Fiber, workInProgress: Fiber) {
// Noop
};
updateHostComponent = function(
Expand Down Expand Up @@ -442,13 +463,13 @@ if (supportsMutation) {
node = node.sibling;
}
};
updateHostContainer = function(workInProgress: Fiber) {
updateHostContainer = function(current: null | Fiber, workInProgress: Fiber) {
const portalOrRoot: {
containerInfo: Container,
pendingChildren: ChildSet,
...
} = workInProgress.stateNode;
const childrenUnchanged = workInProgress.firstEffect === null;
const childrenUnchanged = hadNoMutationsEffects(current, workInProgress);
if (childrenUnchanged) {
// No changes, just reuse the existing instance.
} else {
Expand All @@ -473,7 +494,7 @@ if (supportsMutation) {
const oldProps = current.memoizedProps;
// If there are no effects associated with this node, then none of our children had any updates.
// This guarantees that we can reuse all of them.
const childrenUnchanged = workInProgress.firstEffect === null;
const childrenUnchanged = hadNoMutationsEffects(current, workInProgress);
if (childrenUnchanged && oldProps === newProps) {
// No changes, just reuse the existing instance.
// Note that this might release a previous clone.
Expand Down Expand Up @@ -556,7 +577,7 @@ if (supportsMutation) {
};
} else {
// No host operations
updateHostContainer = function(workInProgress: Fiber) {
updateHostContainer = function(current: null | Fiber, workInProgress: Fiber) {
// Noop
};
updateHostComponent = function(
Expand Down Expand Up @@ -700,7 +721,7 @@ function completeWork(
workInProgress.effectTag |= Snapshot;
}
}
updateHostContainer(workInProgress);
updateHostContainer(current, workInProgress);
return null;
}
case HostComponent: {
Expand Down Expand Up @@ -979,7 +1000,7 @@ function completeWork(
}
case HostPortal:
popHostContainer(workInProgress);
updateHostContainer(workInProgress);
updateHostContainer(current, workInProgress);
if (current === null) {
preparePortalMount(workInProgress.stateNode.containerInfo);
}
Expand Down