Skip to content

Commit bed371a

Browse files
committed
Only use the Timeout update queue to store promises, not for state
It already worked this way in practice.
1 parent c78359f commit bed371a

File tree

2 files changed

+15
-23
lines changed

2 files changed

+15
-23
lines changed

packages/react-reconciler/src/ReactFiberBeginWork.js

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,7 @@ import {
6565
reconcileChildFibers,
6666
cloneChildFibers,
6767
} from './ReactChildFiber';
68-
import {
69-
createUpdate,
70-
enqueueCapturedUpdate,
71-
processUpdateQueue,
72-
ReplaceState,
73-
} from './ReactUpdateQueue';
68+
import {processUpdateQueue} from './ReactUpdateQueue';
7469
import {NoWork, Never} from './ReactFiberExpirationTime';
7570
import {AsyncMode, StrictMode} from './ReactTypeOfMode';
7671
import MAX_SIGNED_31_BIT_INT from './maxSigned31BitInt';
@@ -750,17 +745,12 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
750745
const nextProps = workInProgress.pendingProps;
751746
const prevProps = workInProgress.memoizedProps;
752747

753-
// Unless we already captured a promise during this render, reset the
754-
// placeholder state back to false. We always attempt to render the real
755-
// children before falling back to the placeholder.
756-
if ((workInProgress.effectTag & DidCapture) === NoEffect) {
757-
const update = createUpdate(renderExpirationTime);
758-
update.tag = ReplaceState;
759-
update.payload = false;
760-
enqueueCapturedUpdate(workInProgress, update, renderExpirationTime);
761-
}
748+
const prevDidTimeout = workInProgress.memoizedState;
762749

763-
const prevState = workInProgress.memoizedState;
750+
// The update queue is only used to store expired promises, and to
751+
// schedule a re-render once an expired promise resolves. It does not
752+
// determine whether we should show the placeholder state, because we
753+
// always attempt to show the placeholder state on every render.
764754
const updateQueue = workInProgress.updateQueue;
765755
if (updateQueue !== null) {
766756
processUpdateQueue(
@@ -771,19 +761,24 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
771761
renderExpirationTime,
772762
);
773763
}
774-
const nextState = workInProgress.memoizedState;
764+
765+
// Check if we already attempted to render the normal state. If we did,
766+
// and we timed out, render the placeholder state.
767+
const alreadyCaptured =
768+
(workInProgress.effectTag & DidCapture) === NoEffect;
769+
const nextDidTimeout = !alreadyCaptured;
775770

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

783-
const didTimeout = nextState;
784778
const render = nextProps.children;
785-
const nextChildren = render(didTimeout);
779+
const nextChildren = render(nextDidTimeout);
786780
workInProgress.memoizedProps = nextProps;
781+
workInProgress.memoizedState = nextDidTimeout;
787782
reconcileChildren(current, workInProgress, nextChildren);
788783
return workInProgress.child;
789784
} else {

packages/react-reconciler/src/ReactFiberUnwindWork.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import {
2323
createUpdate,
2424
enqueueUpdate,
2525
CaptureUpdate,
26-
ReplaceState,
2726
} from './ReactUpdateQueue';
2827
import {logError} from './ReactFiberCommitWork';
2928

@@ -269,8 +268,6 @@ export default function<C, CX>(
269268
if ((workInProgress.effectTag & DidCapture) === NoEffect) {
270269
workInProgress.effectTag |= ShouldCapture;
271270
const update = createUpdate(renderExpirationTime);
272-
update.tag = ReplaceState;
273-
update.payload = true;
274271
// Allow var because this is used in a closure.
275272
// eslint-disable-next-line no-var
276273
var finishedWork = workInProgress;

0 commit comments

Comments
 (0)