@@ -20,10 +20,14 @@ import type {FiberRoot} from './ReactInternalTypes';
2020import  type  { Lanes }  from  './ReactFiberLane' ; 
2121import  type  { SuspenseState }  from  './ReactFiberSuspenseComponent.new' ; 
2222import  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' ; 
2427import  type  { Wakeable }  from  'shared/ReactTypes' ; 
2528import  type  { ReactPriorityLevel }  from  './ReactInternalTypes' ; 
2629import  type  { OffscreenState }  from  './ReactFiberOffscreenComponent' ; 
30+ import  type  { HookEffectTag }  from  './ReactHookEffectTags' ; 
2731
2832import  { unstable_wrap  as  Schedule_tracing_wrap }  from  'scheduler/tracing' ; 
2933import  { 
@@ -77,6 +81,8 @@ import {
7781  getCommitTime , 
7882  recordLayoutEffectDuration , 
7983  startLayoutEffectTimer , 
84+   recordPassiveEffectDuration , 
85+   startPassiveEffectTimer , 
8086}  from  './ReactProfilerTimer.new' ; 
8187import  { ProfileMode }  from  './ReactTypeOfMode' ; 
8288import  { 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' ; 
125132import  { didWarnAboutReassigningProps }  from  './ReactFiberBeginWork.new' ; 
126133import  { 
@@ -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+ 
381501export  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+ 
17191871export  { 
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