Skip to content

Commit e7a99f9

Browse files
committedJan 17, 2019
Refactor to use module-level variable instead of effect bit
1 parent 535d76c commit e7a99f9

File tree

3 files changed

+46
-32
lines changed

3 files changed

+46
-32
lines changed
 

‎packages/react-reconciler/src/ReactFiberBeginWork.js

+30-14
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ import {
9090
prepareToReadContext,
9191
calculateChangedBits,
9292
} from './ReactFiberNewContext';
93-
import {resetHooks, renderWithHooks} from './ReactFiberHooks';
93+
import {resetHooks, renderWithHooks, bailoutHooks} from './ReactFiberHooks';
9494
import {stopProfilerTimerIfRunning} from './ReactProfilerTimer';
9595
import {
9696
getMaskedContext,
@@ -128,6 +128,8 @@ import {
128128

129129
const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
130130

131+
let didReceiveUpdate: boolean = false;
132+
131133
let didWarnAboutBadClass;
132134
let didWarnAboutContextTypeOnFunctionComponent;
133135
let didWarnAboutGetDerivedStateOnFunctionComponent;
@@ -260,14 +262,17 @@ function updateForwardRef(
260262
);
261263
}
262264

263-
if ((workInProgress.effectTag & PerformedWork) === NoEffect) {
265+
if (current !== null && !didReceiveUpdate) {
266+
bailoutHooks(current, workInProgress, renderExpirationTime);
264267
return bailoutOnAlreadyFinishedWork(
265268
current,
266269
workInProgress,
267270
renderExpirationTime,
268271
);
269272
}
270273

274+
// React DevTools reads this flag.
275+
workInProgress.effectTag |= PerformedWork;
271276
reconcileChildren(
272277
current,
273278
workInProgress,
@@ -368,6 +373,8 @@ function updateMemoComponent(
368373
);
369374
}
370375
}
376+
// React DevTools reads this flag.
377+
workInProgress.effectTag |= PerformedWork;
371378
let newChild = createWorkInProgress(
372379
currentChild,
373380
nextProps,
@@ -411,17 +418,20 @@ function updateSimpleMemoComponent(
411418
// Inner propTypes will be validated in the function component path.
412419
}
413420
}
414-
if (current !== null && updateExpirationTime < renderExpirationTime) {
421+
if (current !== null) {
415422
const prevProps = current.memoizedProps;
416423
if (
417424
shallowEqual(prevProps, nextProps) &&
418425
current.ref === workInProgress.ref
419426
) {
420-
return bailoutOnAlreadyFinishedWork(
421-
current,
422-
workInProgress,
423-
renderExpirationTime,
424-
);
427+
didReceiveUpdate = false;
428+
if (updateExpirationTime < renderExpirationTime) {
429+
return bailoutOnAlreadyFinishedWork(
430+
current,
431+
workInProgress,
432+
renderExpirationTime,
433+
);
434+
}
425435
}
426436
}
427437
return updateFunctionComponent(
@@ -545,14 +555,16 @@ function updateFunctionComponent(
545555
);
546556
}
547557

548-
if ((workInProgress.effectTag & PerformedWork) === NoEffect) {
558+
if (current !== null && !didReceiveUpdate) {
559+
bailoutHooks(current, workInProgress, renderExpirationTime);
549560
return bailoutOnAlreadyFinishedWork(
550561
current,
551562
workInProgress,
552563
renderExpirationTime,
553564
);
554565
}
555566

567+
workInProgress.effectTag |= PerformedWork;
556568
reconcileChildren(
557569
current,
558570
workInProgress,
@@ -1142,6 +1154,8 @@ function mountIndeterminateComponent(
11421154
renderExpirationTime,
11431155
);
11441156
}
1157+
// React DevTools reads this flag.
1158+
workInProgress.effectTag |= PerformedWork;
11451159

11461160
if (
11471161
typeof value === 'object' &&
@@ -1682,6 +1696,10 @@ function updateContextConsumer(
16821696
return workInProgress.child;
16831697
}
16841698

1699+
export function markWorkInProgressReceivedUpdate() {
1700+
didReceiveUpdate = true;
1701+
}
1702+
16851703
function bailoutOnAlreadyFinishedWork(
16861704
current: Fiber | null,
16871705
workInProgress: Fiber,
@@ -1694,8 +1712,6 @@ function bailoutOnAlreadyFinishedWork(
16941712
workInProgress.contextDependencies = current.contextDependencies;
16951713
}
16961714

1697-
workInProgress.effectTag &= ~PerformedWork;
1698-
16991715
if (enableProfilerTimer) {
17001716
// Don't update "base" render times for bailouts.
17011717
stopProfilerTimerIfRunning(workInProgress);
@@ -1730,8 +1746,9 @@ function beginWork(
17301746
if (oldProps !== newProps || hasLegacyContextChanged()) {
17311747
// If props or context changed, mark the fiber as having performed work.
17321748
// This may be unset if the props are determined to be equal later (memo).
1733-
workInProgress.effectTag |= PerformedWork;
1749+
didReceiveUpdate = true;
17341750
} else if (updateExpirationTime < renderExpirationTime) {
1751+
didReceiveUpdate = false;
17351752
// This fiber does not have any pending work. Bailout without entering
17361753
// the begin phase. There's still some bookkeeping we that needs to be done
17371754
// in this optimized path, mostly pushing stuff onto the stack.
@@ -1815,8 +1832,7 @@ function beginWork(
18151832
);
18161833
}
18171834
} else {
1818-
// No bailouts on initial mount.
1819-
workInProgress.effectTag |= PerformedWork;
1835+
didReceiveUpdate = false;
18201836
}
18211837

18221838
// Before entering the begin phase, clear the expiration time.

‎packages/react-reconciler/src/ReactFiberHooks.js

+14-16
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ import {readContext} from './ReactFiberNewContext';
1818
import {
1919
Update as UpdateEffect,
2020
Passive as PassiveEffect,
21-
PerformedWork,
22-
NoEffect,
2321
} from 'shared/ReactSideEffectTags';
2422
import {
2523
NoEffect as NoHookEffect,
@@ -37,6 +35,7 @@ import {
3735

3836
import invariant from 'shared/invariant';
3937
import areHookInputsEqual from 'shared/areHookInputsEqual';
38+
import {markWorkInProgressReceivedUpdate} from './ReactFiberBeginWork';
4039

4140
type Update<S, A> = {
4241
expirationTime: ExpirationTime,
@@ -171,18 +170,6 @@ export function renderWithHooks(
171170

172171
const renderedWork: Fiber = (currentlyRenderingFiber: any);
173172

174-
if (
175-
current !== null &&
176-
(renderedWork.effectTag & PerformedWork) === NoEffect
177-
) {
178-
// If nothing updated, clear the effects. We're going to bail out.
179-
componentUpdateQueue = (current.updateQueue: any);
180-
renderedWork.effectTag &= ~(PassiveEffect | UpdateEffect);
181-
if (current.expirationTime <= renderExpirationTime) {
182-
current.expirationTime = NoWork;
183-
}
184-
}
185-
186173
renderedWork.memoizedState = firstWorkInProgressHook;
187174
renderedWork.expirationTime = remainingExpirationTime;
188175
renderedWork.updateQueue = componentUpdateQueue;
@@ -218,6 +205,18 @@ export function renderWithHooks(
218205
return children;
219206
}
220207

208+
export function bailoutHooks(
209+
current: Fiber,
210+
workInProgress: Fiber,
211+
expirationTime: ExpirationTime,
212+
) {
213+
workInProgress.updateQueue = current.updateQueue;
214+
workInProgress.effectTag &= ~(PassiveEffect | UpdateEffect);
215+
if (current.expirationTime <= expirationTime) {
216+
current.expirationTime = NoWork;
217+
}
218+
}
219+
221220
export function resetHooks(): void {
222221
if (!enableHooks) {
223222
return;
@@ -462,7 +461,7 @@ export function useReducer<S, A>(
462461
// Mark that the fiber performed work, but only if the new state is
463462
// different from the current state.
464463
if (newState !== (currentHook: any).memoizedState) {
465-
currentlyRenderingFiber.effectTag |= PerformedWork;
464+
markWorkInProgressReceivedUpdate();
466465
}
467466

468467
queue.eagerReducer = reducer;
@@ -489,7 +488,6 @@ export function useReducer<S, A>(
489488
eagerReducer: reducer,
490489
eagerState: initialState,
491490
};
492-
currentlyRenderingFiber.effectTag |= PerformedWork;
493491
const dispatch: Dispatch<A> = (queue.dispatch = (dispatchAction.bind(
494492
null,
495493
currentlyRenderingFiber,

‎packages/react-reconciler/src/ReactFiberNewContext.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import {
3838
ForceUpdate,
3939
} from 'react-reconciler/src/ReactUpdateQueue';
4040
import {NoWork} from './ReactFiberExpirationTime';
41-
import {PerformedWork} from 'shared/ReactSideEffectTags';
41+
import {markWorkInProgressReceivedUpdate} from './ReactFiberBeginWork';
4242

4343
const valueCursor: StackCursor<mixed> = createCursor(null);
4444

@@ -268,7 +268,7 @@ export function prepareToReadContext(
268268
currentDependencies.expirationTime >= renderExpirationTime
269269
) {
270270
// Context list has a pending update. Mark that this fiber performed work.
271-
workInProgress.effectTag |= PerformedWork;
271+
markWorkInProgressReceivedUpdate();
272272
}
273273

274274
// Reset the work-in-progress list

0 commit comments

Comments
 (0)