Skip to content

Commit

Permalink
Only use the Timeout update queue to store promises, not for state
Browse files Browse the repository at this point in the history
It already worked this way in practice.
  • Loading branch information
acdlite committed Apr 24, 2018
1 parent a04cd32 commit 58cd090
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 23 deletions.
35 changes: 15 additions & 20 deletions packages/react-reconciler/src/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,7 @@ import {
reconcileChildFibers,
cloneChildFibers,
} from './ReactChildFiber';
import {
createUpdate,
enqueueCapturedUpdate,
processUpdateQueue,
ReplaceState,
} from './ReactUpdateQueue';
import {processUpdateQueue} from './ReactUpdateQueue';
import {NoWork, Never} from './ReactFiberExpirationTime';
import {AsyncMode, StrictMode} from './ReactTypeOfMode';
import MAX_SIGNED_31_BIT_INT from './maxSigned31BitInt';
Expand Down Expand Up @@ -740,17 +735,12 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
const nextProps = workInProgress.pendingProps;
const prevProps = workInProgress.memoizedProps;

// Unless we already captured a promise during this render, reset the
// placeholder state back to false. We always attempt to render the real
// children before falling back to the placeholder.
if ((workInProgress.effectTag & DidCapture) === NoEffect) {
const update = createUpdate(renderExpirationTime);
update.tag = ReplaceState;
update.payload = false;
enqueueCapturedUpdate(workInProgress, update, renderExpirationTime);
}
const prevDidTimeout = workInProgress.memoizedState;

const prevState = workInProgress.memoizedState;
// The update queue is only used to store expired promises, and to
// schedule a re-render once an expired promise resolves. It does not
// determine whether we should show the placeholder state, because we
// always attempt to show the placeholder state on every render.
const updateQueue = workInProgress.updateQueue;
if (updateQueue !== null) {
processUpdateQueue(
Expand All @@ -761,19 +751,24 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
renderExpirationTime,
);
}
const nextState = workInProgress.memoizedState;

// Check if we already attempted to render the normal state. If we did,
// and we timed out, render the placeholder state.
const alreadyCaptured =
(workInProgress.effectTag & DidCapture) === NoEffect;
const nextDidTimeout = !alreadyCaptured;

if (hasLegacyContextChanged()) {
// Normally we can bail out on props equality but if context has changed
// we don't do the bailout and we have to reuse existing props instead.
} else if (nextProps === prevProps && nextState === prevState) {
} else if (nextProps === prevProps && nextDidTimeout === prevDidTimeout) {
return bailoutOnAlreadyFinishedWork(current, workInProgress);
}

const didTimeout = nextState;
const render = nextProps.children;
const nextChildren = render(didTimeout);
const nextChildren = render(nextDidTimeout);
workInProgress.memoizedProps = nextProps;
workInProgress.memoizedState = nextDidTimeout;
reconcileChildren(current, workInProgress, nextChildren);
return workInProgress.child;
} else {
Expand Down
3 changes: 0 additions & 3 deletions packages/react-reconciler/src/ReactFiberUnwindWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
createUpdate,
enqueueUpdate,
CaptureUpdate,
ReplaceState,
} from './ReactUpdateQueue';
import {logError} from './ReactFiberCommitWork';

Expand Down Expand Up @@ -267,8 +266,6 @@ export default function<C, CX>(
if ((workInProgress.effectTag & DidCapture) === NoEffect) {
workInProgress.effectTag |= ShouldCapture;
const update = createUpdate(renderExpirationTime);
update.tag = ReplaceState;
update.payload = true;
// Allow var because this is used in a closure.
// eslint-disable-next-line no-var
var finishedWork = workInProgress;
Expand Down

0 comments on commit 58cd090

Please sign in to comment.