Move commit passive unmount/mount to CommitWork (#19599)
Sebastian Markbåge committed
Aug 13, 2020 at 12:17 UTC
dab0854c5e66ca74ca0591fd312d6a654e5aaaf1
2 files changed
+172
-152
packages/react-reconciler/src/ReactFiberCommitWork.new.js
+159
-4
@@ -20,10 +20,14 @@ import type {FiberRoot} from './ReactInternalTypes';
20
import type {Lanes} from './ReactFiberLane';
21
import type {SuspenseState} from './ReactFiberSuspenseComponent.new';
22
import type {UpdateQueue} from './ReactUpdateQueue.new';
23
-import type {FunctionComponentUpdateQueue} from './ReactFiberHooks.new';
23
+import type {
24
+ Effect as HookEffect,
25
+ FunctionComponentUpdateQueue,
26
+} from './ReactFiberHooks.new';
27
import type {Wakeable} from 'shared/ReactTypes';
28
import type {ReactPriorityLevel} from './ReactInternalTypes';
29
import type {OffscreenState} from './ReactFiberOffscreenComponent';
30
+import type {HookEffectTag} from './ReactHookEffectTags';
31
32
import {unstable_wrap as Schedule_tracing_wrap} from 'scheduler/tracing';
33
import {
@@ -77,6 +81,8 @@ import {
81
getCommitTime,
82
recordLayoutEffectDuration,
83
startLayoutEffectTimer,
84
+ recordPassiveEffectDuration,
85
+ startPassiveEffectTimer,
86
} from './ReactProfilerTimer.new';
87
import {ProfileMode} from './ReactTypeOfMode';
88
import {commitUpdateQueue} from './ReactUpdateQueue.new';
@@ -121,6 +127,7 @@ import {
127
NoEffect as NoHookEffect,
128
HasEffect as HookHasEffect,
129
Layout as HookLayout,
130
+ Passive as HookPassive,
131
} from './ReactHookEffectTags';
132
import {didWarnAboutReassigningProps} from './ReactFiberBeginWork.new';
133
import {
@@ -308,7 +315,7 @@ function commitBeforeMutationLifeCycles(
315
);
316
}
317
311
-function commitHookEffectListUnmount(tag: number, finishedWork: Fiber) {
318
+function commitHookEffectListUnmount(tag: HookEffectTag, finishedWork: Fiber) {
319
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
320
const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
321
if (lastEffect !== null) {
@@ -328,7 +335,43 @@ function commitHookEffectListUnmount(tag: number, finishedWork: Fiber) {
335
}
336
}
337
331
-function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
338
+// TODO: Remove this duplication.
339
+function commitHookEffectListUnmount2(
340
+ // Tags to check for when deciding whether to unmount. e.g. to skip over
341
+ // layout effects
342
+ hookEffectTag: HookEffectTag,
343
+ fiber: Fiber,
344
+): void {
345
+ const updateQueue: FunctionComponentUpdateQueue | null = (fiber.updateQueue: any);
346
+ const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
347
+ if (lastEffect !== null) {
348
+ const firstEffect = lastEffect.next;
349
+ let effect = firstEffect;
350
+ do {
351
+ const {next, tag} = effect;
352
+ if ((tag & hookEffectTag) === hookEffectTag) {
353
+ const destroy = effect.destroy;
354
+ if (destroy !== undefined) {
355
+ effect.destroy = undefined;
356
+ if (
357
+ enableProfilerTimer &&
358
+ enableProfilerCommitHooks &&
359
+ fiber.mode & ProfileMode
360
+ ) {
361
+ startPassiveEffectTimer();
362
+ safelyCallDestroy(fiber, destroy);
363
+ recordPassiveEffectDuration(fiber);
364
+ } else {
365
+ safelyCallDestroy(fiber, destroy);
366
+ }
367
+ }
368
+ }
369
+ effect = next;
370
+ } while (effect !== firstEffect);
371
+ }
372
+}
373
+
374
+function commitHookEffectListMount(tag: HookEffectTag, finishedWork: Fiber) {
375
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
376
const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
377
if (lastEffect !== null) {
@@ -378,6 +421,83 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
421
}
422
}
423
424
+function invokePassiveEffectCreate(effect: HookEffect): void {
425
+ const create = effect.create;
426
+ effect.destroy = create();
427
+}
428
+
429
+// TODO: Remove this duplication.
430
+function commitHookEffectListMount2(fiber: Fiber): void {
431
+ const updateQueue: FunctionComponentUpdateQueue | null = (fiber.updateQueue: any);
432
+ const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
433
+ if (lastEffect !== null) {
434
+ const firstEffect = lastEffect.next;
435
+ let effect = firstEffect;
436
+ do {
437
+ const {next, tag} = effect;
438
+
439
+ if (
440
+ (tag & HookPassive) !== NoHookEffect &&
441
+ (tag & HookHasEffect) !== NoHookEffect
442
+ ) {
443
+ if (__DEV__) {
444
+ if (
445
+ enableProfilerTimer &&
446
+ enableProfilerCommitHooks &&
447
+ fiber.mode & ProfileMode
448
+ ) {
449
+ startPassiveEffectTimer();
450
+ invokeGuardedCallback(
451
+ null,
452
+ invokePassiveEffectCreate,
453
+ null,
454
+ effect,
455
+ );
456
+ recordPassiveEffectDuration(fiber);
457
+ } else {
458
+ invokeGuardedCallback(
459
+ null,
460
+ invokePassiveEffectCreate,
461
+ null,
462
+ effect,
463
+ );
464
+ }
465
+ if (hasCaughtError()) {
466
+ invariant(fiber !== null, 'Should be working on an effect.');
467
+ const error = clearCaughtError();
468
+ captureCommitPhaseError(fiber, error);
469
+ }
470
+ } else {
471
+ try {
472
+ const create = effect.create;
473
+ if (
474
+ enableProfilerTimer &&
475
+ enableProfilerCommitHooks &&
476
+ fiber.mode & ProfileMode
477
+ ) {
478
+ try {
479
+ startPassiveEffectTimer();
480
+ effect.destroy = create();
481
+ } finally {
482
+ recordPassiveEffectDuration(fiber);
483
+ }
484
+ } else {
485
+ effect.destroy = create();
486
+ }
487
+ // TODO: This is missing the warning that exists in commitHookEffectListMount.
488
+ // The warning refers to useEffect but only applies to useLayoutEffect.
489
+ } catch (error) {
490
+ invariant(fiber !== null, 'Should be working on an effect.');
491
+ captureCommitPhaseError(fiber, error);
492
+ }
493
+ }
494
+ }
495
+
496
+ effect = next;
497
+ } while (effect !== firstEffect);
498
+ }
499
+}
500
+
501
export function commitPassiveEffectDurations(
502
finishedRoot: FiberRoot,
503
finishedWork: Fiber,
@@ -1709,13 +1829,45 @@ export function isSuspenseBoundaryBeingHidden(
1829
return false;
1830
}
1831
1712
-function commitResetTextContent(current: Fiber) {
1832
+function commitResetTextContent(current: Fiber): void {
1833
if (!supportsMutation) {
1834
return;
1835
}
1836
resetTextContent(current.stateNode);
1837
}
1838
1839
+function commitPassiveWork(finishedWork: Fiber): void {
1840
+ switch (finishedWork.tag) {
1841
+ case FunctionComponent:
1842
+ case ForwardRef:
1843
+ case SimpleMemoComponent:
1844
+ case Block: {
1845
+ commitHookEffectListUnmount2(HookPassive | HookHasEffect, finishedWork);
1846
+ }
1847
+ }
1848
+}
1849
+
1850
+function commitPassiveUnmount(current: Fiber): void {
1851
+ switch (current.tag) {
1852
+ case FunctionComponent:
1853
+ case ForwardRef:
1854
+ case SimpleMemoComponent:
1855
+ case Block:
1856
+ commitHookEffectListUnmount2(HookPassive, current);
1857
+ }
1858
+}
1859
+
1860
+function commitPassiveLifeCycles(finishedWork: Fiber): void {
1861
+ switch (finishedWork.tag) {
1862
+ case FunctionComponent:
1863
+ case ForwardRef:
1864
+ case SimpleMemoComponent:
1865
+ case Block: {
1866
+ commitHookEffectListMount2(finishedWork);
1867
+ }
1868
+ }
1869
+}
1870
+
1871
export {
1872
commitBeforeMutationLifeCycles,
1873
commitResetTextContent,
@@ -1725,4 +1877,7 @@ export {
1877
commitLifeCycles,
1878
commitAttachRef,
1879
commitDetachRef,
1880
+ commitPassiveUnmount,
1881
+ commitPassiveWork,
1882
+ commitPassiveLifeCycles,
1883
};
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+13
-148
@@ -14,8 +14,6 @@ import type {ReactPriorityLevel} from './ReactInternalTypes';
14
import type {Interaction} from 'scheduler/src/Tracing';
15
import type {SuspenseConfig} from './ReactFiberSuspenseConfig';
16
import type {SuspenseState} from './ReactFiberSuspenseComponent.new';
17
-import type {Effect as HookEffect} from './ReactFiberHooks.new';
18
-import type {HookEffectTag} from './ReactHookEffectTags';
17
import type {StackCursor} from './ReactFiberStack.new';
18
import type {FunctionComponentUpdateQueue} from './ReactFiberHooks.new';
19
@@ -53,7 +51,6 @@ import {
51
} from './SchedulerWithReactIntegration.new';
52
import {
53
NoEffect as NoHookEffect,
56
- HasEffect as HookHasEffect,
54
Passive as HookPassive,
55
} from './ReactHookEffectTags';
56
import {
@@ -206,12 +203,14 @@ import {
203
commitPlacement,
204
commitWork,
205
commitDeletion,
206
+ commitPassiveUnmount,
207
+ commitPassiveWork,
208
+ commitPassiveLifeCycles as commitPassiveEffectOnFiber,
209
commitDetachRef,
210
commitAttachRef,
211
commitPassiveEffectDurations,
212
commitResetTextContent,
213
isSuspenseBoundaryBeingHidden,
214
- safelyCallDestroy,
214
} from './ReactFiberCommitWork.new';
215
import {enqueueUpdate} from './ReactUpdateQueue.new';
216
import {resetContextDependencies} from './ReactFiberNewContext.new';
@@ -229,8 +228,6 @@ import {
228
229
import {
230
recordCommitTime,
232
- recordPassiveEffectDuration,
233
- startPassiveEffectTimer,
231
startProfilerTimer,
232
stopProfilerTimerIfRunningAndRecordDelta,
233
} from './ReactProfilerTimer.new';
@@ -2738,11 +2735,6 @@ export function enqueuePendingPassiveProfilerEffect(fiber: Fiber): void {
2735
}
2736
}
2737
2741
-function invokePassiveEffectCreate(effect: HookEffect): void {
2742
- const create = effect.create;
2743
- effect.destroy = create();
2744
-}
2745
-
2738
function flushPassiveMountEffects(firstChild: Fiber): void {
2739
let fiber = firstChild;
2740
while (fiber !== null) {
@@ -2753,93 +2745,15 @@ function flushPassiveMountEffects(firstChild: Fiber): void {
2745
}
2746
2747
if ((fiber.effectTag & Update) !== NoEffect) {
2756
- switch (fiber.tag) {
2757
- case FunctionComponent:
2758
- case ForwardRef:
2759
- case SimpleMemoComponent:
2760
- case Block: {
2761
- flushPassiveMountEffectsImpl(fiber);
2762
- }
2763
- }
2748
+ setCurrentDebugFiberInDEV(fiber);
2749
+ commitPassiveEffectOnFiber(fiber);
2750
+ resetCurrentDebugFiberInDEV();
2751
}
2752
2753
fiber = fiber.sibling;
2754
}
2755
}
2756
2770
-function flushPassiveMountEffectsImpl(fiber: Fiber): void {
2771
- setCurrentDebugFiberInDEV(fiber);
2772
-
2773
- const updateQueue: FunctionComponentUpdateQueue | null = (fiber.updateQueue: any);
2774
- const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
2775
- if (lastEffect !== null) {
2776
- const firstEffect = lastEffect.next;
2777
- let effect = firstEffect;
2778
- do {
2779
- const {next, tag} = effect;
2780
-
2781
- if (
2782
- (tag & HookPassive) !== NoHookEffect &&
2783
- (tag & HookHasEffect) !== NoHookEffect
2784
- ) {
2785
- if (__DEV__) {
2786
- if (
2787
- enableProfilerTimer &&
2788
- enableProfilerCommitHooks &&
2789
- fiber.mode & ProfileMode
2790
- ) {
2791
- startPassiveEffectTimer();
2792
- invokeGuardedCallback(
2793
- null,
2794
- invokePassiveEffectCreate,
2795
- null,
2796
- effect,
2797
- );
2798
- recordPassiveEffectDuration(fiber);
2799
- } else {
2800
- invokeGuardedCallback(
2801
- null,
2802
- invokePassiveEffectCreate,
2803
- null,
2804
- effect,
2805
- );
2806
- }
2807
- if (hasCaughtError()) {
2808
- invariant(fiber !== null, 'Should be working on an effect.');
2809
- const error = clearCaughtError();
2810
- captureCommitPhaseError(fiber, error);
2811
- }
2812
- } else {
2813
- try {
2814
- const create = effect.create;
2815
- if (
2816
- enableProfilerTimer &&
2817
- enableProfilerCommitHooks &&
2818
- fiber.mode & ProfileMode
2819
- ) {
2820
- try {
2821
- startPassiveEffectTimer();
2822
- effect.destroy = create();
2823
- } finally {
2824
- recordPassiveEffectDuration(fiber);
2825
- }
2826
- } else {
2827
- effect.destroy = create();
2828
- }
2829
- } catch (error) {
2830
- invariant(fiber !== null, 'Should be working on an effect.');
2831
- captureCommitPhaseError(fiber, error);
2832
- }
2833
- }
2834
- }
2835
-
2836
- effect = next;
2837
- } while (effect !== firstEffect);
2838
-
2839
- resetCurrentDebugFiberInDEV();
2840
- }
2841
-}
2842
-
2757
function flushPassiveUnmountEffects(firstChild: Fiber): void {
2758
let fiber = firstChild;
2759
while (fiber !== null) {
@@ -2866,16 +2780,11 @@ function flushPassiveUnmountEffects(firstChild: Fiber): void {
2780
}
2781
}
2782
2869
- switch (fiber.tag) {
2870
- case FunctionComponent:
2871
- case ForwardRef:
2872
- case SimpleMemoComponent:
2873
- case Block: {
2874
- const primaryEffectTag = fiber.effectTag & Passive;
2875
- if (primaryEffectTag !== NoEffect) {
2876
- flushPassiveUnmountEffectsImpl(fiber, HookPassive | HookHasEffect);
2877
- }
2878
- }
2783
+ const primaryEffectTag = fiber.effectTag & Passive;
2784
+ if (primaryEffectTag !== NoEffect) {
2785
+ setCurrentDebugFiberInDEV(fiber);
2786
+ commitPassiveWork(fiber);
2787
+ resetCurrentDebugFiberInDEV();
2788
}
2789
2790
fiber = fiber.sibling;
@@ -2898,52 +2807,8 @@ function flushPassiveUnmountEffectsInsideOfDeletedTree(
2807
}
2808
2809
if ((fiberToDelete.effectTag & PassiveStatic) !== NoEffect) {
2901
- switch (fiberToDelete.tag) {
2902
- case FunctionComponent:
2903
- case ForwardRef:
2904
- case SimpleMemoComponent:
2905
- case Block: {
2906
- flushPassiveUnmountEffectsImpl(fiberToDelete, HookPassive);
2907
- }
2908
- }
2909
- }
2910
-}
2911
-
2912
-function flushPassiveUnmountEffectsImpl(
2913
- fiber: Fiber,
2914
- // Tags to check for when deciding whether to unmount. e.g. to skip over
2915
- // layout effects
2916
- hookEffectTag: HookEffectTag,
2917
-): void {
2918
- const updateQueue: FunctionComponentUpdateQueue | null = (fiber.updateQueue: any);
2919
- const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
2920
- if (lastEffect !== null) {
2921
- setCurrentDebugFiberInDEV(fiber);
2922
-
2923
- const firstEffect = lastEffect.next;
2924
- let effect = firstEffect;
2925
- do {
2926
- const {next, tag} = effect;
2927
- if ((tag & hookEffectTag) === hookEffectTag) {
2928
- const destroy = effect.destroy;
2929
- if (destroy !== undefined) {
2930
- effect.destroy = undefined;
2931
- if (
2932
- enableProfilerTimer &&
2933
- enableProfilerCommitHooks &&
2934
- fiber.mode & ProfileMode
2935
- ) {
2936
- startPassiveEffectTimer();
2937
- safelyCallDestroy(fiber, destroy);
2938
- recordPassiveEffectDuration(fiber);
2939
- } else {
2940
- safelyCallDestroy(fiber, destroy);
2941
- }
2942
- }
2943
- }
2944
- effect = next;
2945
- } while (effect !== firstEffect);
2946
-
2810
+ setCurrentDebugFiberInDEV(fiberToDelete);
2811
+ commitPassiveUnmount(fiberToDelete);
2812
resetCurrentDebugFiberInDEV();
2813
}
2814
}