Skip to content

Commit dab0854

Browse files
authored
Move commit passive unmount/mount to CommitWork (#19599)
1 parent c3ee973 commit dab0854

File tree

2 files changed

+172
-152
lines changed

2 files changed

+172
-152
lines changed

packages/react-reconciler/src/ReactFiberCommitWork.new.js

+159-4
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ import type {FiberRoot} from './ReactInternalTypes';
2020
import type {Lanes} from './ReactFiberLane';
2121
import type {SuspenseState} from './ReactFiberSuspenseComponent.new';
2222
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';
2427
import type {Wakeable} from 'shared/ReactTypes';
2528
import type {ReactPriorityLevel} from './ReactInternalTypes';
2629
import type {OffscreenState} from './ReactFiberOffscreenComponent';
30+
import type {HookEffectTag} from './ReactHookEffectTags';
2731

2832
import {unstable_wrap as Schedule_tracing_wrap} from 'scheduler/tracing';
2933
import {
@@ -77,6 +81,8 @@ import {
7781
getCommitTime,
7882
recordLayoutEffectDuration,
7983
startLayoutEffectTimer,
84+
recordPassiveEffectDuration,
85+
startPassiveEffectTimer,
8086
} from './ReactProfilerTimer.new';
8187
import {ProfileMode} from './ReactTypeOfMode';
8288
import {commitUpdateQueue} from './ReactUpdateQueue.new';
@@ -121,6 +127,7 @@ import {
121127
NoEffect as NoHookEffect,
122128
HasEffect as HookHasEffect,
123129
Layout as HookLayout,
130+
Passive as HookPassive,
124131
} from './ReactHookEffectTags';
125132
import {didWarnAboutReassigningProps} from './ReactFiberBeginWork.new';
126133
import {
@@ -308,7 +315,7 @@ function commitBeforeMutationLifeCycles(
308315
);
309316
}
310317

311-
function commitHookEffectListUnmount(tag: number, finishedWork: Fiber) {
318+
function commitHookEffectListUnmount(tag: HookEffectTag, finishedWork: Fiber) {
312319
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
313320
const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
314321
if (lastEffect !== null) {
@@ -328,7 +335,43 @@ function commitHookEffectListUnmount(tag: number, finishedWork: Fiber) {
328335
}
329336
}
330337

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) {
332375
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
333376
const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
334377
if (lastEffect !== null) {
@@ -378,6 +421,83 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
378421
}
379422
}
380423

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+
381501
export function commitPassiveEffectDurations(
382502
finishedRoot: FiberRoot,
383503
finishedWork: Fiber,
@@ -1709,13 +1829,45 @@ export function isSuspenseBoundaryBeingHidden(
17091829
return false;
17101830
}
17111831

1712-
function commitResetTextContent(current: Fiber) {
1832+
function commitResetTextContent(current: Fiber): void {
17131833
if (!supportsMutation) {
17141834
return;
17151835
}
17161836
resetTextContent(current.stateNode);
17171837
}
17181838

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+
17191871
export {
17201872
commitBeforeMutationLifeCycles,
17211873
commitResetTextContent,
@@ -1725,4 +1877,7 @@ export {
17251877
commitLifeCycles,
17261878
commitAttachRef,
17271879
commitDetachRef,
1880+
commitPassiveUnmount,
1881+
commitPassiveWork,
1882+
commitPassiveLifeCycles,
17281883
};

0 commit comments

Comments
 (0)