Skip to content

Commit

Permalink
Schedule placement effect on indeterminate components
Browse files Browse the repository at this point in the history
In non-concurrent mode, indeterminate fibers may commit in an
inconsistent state. But when they update, we should throw out the
old fiber and start fresh. Which means the new fiber needs a
placement effect.
  • Loading branch information
acdlite committed Oct 18, 2018
1 parent c78f360 commit 36ce895
Showing 1 changed file with 7 additions and 45 deletions.
52 changes: 7 additions & 45 deletions packages/react-reconciler/src/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ function resolveDefaultProps(Component, baseProps) {
return baseProps;
}

function updateIndeterminateComponent(
function mountIndeterminateComponent(
current,
workInProgress,
Component,
Expand All @@ -721,11 +721,9 @@ function updateIndeterminateComponent(
// Disconnect the alternate pointers.
current.alternate = null;
workInProgress.alternate = null;
// Don't assign the `current` variable to null, though, since reconcileChildren uses the
// existence of current as a heuristic for whether to schedule placement
// effects on the children. This is super weird but reconcileChildren is
// deeply nested and it doesn't seem worth it to refactor for this edge
// case. (There are unit tests to prevent regressions.)
current = null;
// Since this is conceptually a new fiber, schedule a Placement effect
workInProgress.effectTag |= Placement;
}

const props = workInProgress.pendingProps;
Expand Down Expand Up @@ -757,47 +755,11 @@ function updateIndeterminateComponent(
break;
}
case ClassComponentLazy: {
// This is a fork of updateClassComponent
let hasContext;
if (isLegacyContextProvider(Component)) {
hasContext = true;
pushLegacyContextProvider(workInProgress);
} else {
hasContext = false;
}
prepareToReadContext(workInProgress, renderExpirationTime);

let shouldUpdate;
if (workInProgress.stateNode === null) {
// In the initial pass we might need to construct the instance.
constructClassInstance(
workInProgress,
Component,
props,
renderExpirationTime,
);
mountClassInstance(
workInProgress,
Component,
props,
renderExpirationTime,
);
shouldUpdate = true;
} else {
// In a resume, we'll already have an instance we can reuse.
shouldUpdate = resumeMountClassInstance(
workInProgress,
Component,
props,
renderExpirationTime,
);
}
child = finishClassComponent(
child = updateClassComponent(
current,
workInProgress,
Component,
shouldUpdate,
hasContext,
resolvedProps,
renderExpirationTime,
);
break;
Expand Down Expand Up @@ -1521,7 +1483,7 @@ function beginWork(
switch (workInProgress.tag) {
case IndeterminateComponent: {
const Component = workInProgress.type;
return updateIndeterminateComponent(
return mountIndeterminateComponent(
current,
workInProgress,
Component,
Expand Down

0 comments on commit 36ce895

Please sign in to comment.