Skip to content

Commit 58cd090

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

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';
@@ -740,17 +735,12 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
740735
const nextProps = workInProgress.pendingProps;
741736
const prevProps = workInProgress.memoizedProps;
742737

743-
// Unless we already captured a promise during this render, reset the
744-
// placeholder state back to false. We always attempt to render the real
745-
// children before falling back to the placeholder.
746-
if ((workInProgress.effectTag & DidCapture) === NoEffect) {
747-
const update = createUpdate(renderExpirationTime);
748-
update.tag = ReplaceState;
749-
update.payload = false;
750-
enqueueCapturedUpdate(workInProgress, update, renderExpirationTime);
751-
}
738+
const prevDidTimeout = workInProgress.memoizedState;
752739

753-
const prevState = workInProgress.memoizedState;
740+
// The update queue is only used to store expired promises, and to
741+
// schedule a re-render once an expired promise resolves. It does not
742+
// determine whether we should show the placeholder state, because we
743+
// always attempt to show the placeholder state on every render.
754744
const updateQueue = workInProgress.updateQueue;
755745
if (updateQueue !== null) {
756746
processUpdateQueue(
@@ -761,19 +751,24 @@ export default function<T, P, I, TI, HI, PI, C, CC, CX, PL>(
761751
renderExpirationTime,
762752
);
763753
}
764-
const nextState = workInProgress.memoizedState;
754+
755+
// Check if we already attempted to render the normal state. If we did,
756+
// and we timed out, render the placeholder state.
757+
const alreadyCaptured =
758+
(workInProgress.effectTag & DidCapture) === NoEffect;
759+
const nextDidTimeout = !alreadyCaptured;
765760

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

773-
const didTimeout = nextState;
774768
const render = nextProps.children;
775-
const nextChildren = render(didTimeout);
769+
const nextChildren = render(nextDidTimeout);
776770
workInProgress.memoizedProps = nextProps;
771+
workInProgress.memoizedState = nextDidTimeout;
777772
reconcileChildren(current, workInProgress, nextChildren);
778773
return workInProgress.child;
779774
} 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

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

0 commit comments

Comments
 (0)