@@ -60,10 +60,10 @@ import {
60
60
Hydrating ,
61
61
ContentReset ,
62
62
DidCapture ,
63
- Update ,
64
63
Ref ,
65
64
Deletion ,
66
65
ForceUpdateForLegacySuspense ,
66
+ StaticMask ,
67
67
} from './ReactFiberFlags' ;
68
68
import ReactSharedInternals from 'shared/ReactSharedInternals' ;
69
69
import {
@@ -674,8 +674,6 @@ function updateProfiler(
674
674
renderLanes : Lanes ,
675
675
) {
676
676
if ( enableProfilerTimer ) {
677
- workInProgress . flags |= Update ;
678
-
679
677
// Reset effect durations for the next eventual effect phase.
680
678
// These are reset during render to allow the DevTools commit hook a chance to read them,
681
679
const stateNode = workInProgress . stateNode ;
@@ -1151,6 +1149,9 @@ function updateHostComponent(
1151
1149
workInProgress . flags |= ContentReset ;
1152
1150
}
1153
1151
1152
+ // React DevTools reads this flag.
1153
+ workInProgress . flags |= PerformedWork ;
1154
+
1154
1155
markRef ( current , workInProgress ) ;
1155
1156
reconcileChildren ( current , workInProgress , nextChildren , renderLanes ) ;
1156
1157
return workInProgress . child ;
@@ -2090,9 +2091,14 @@ function updateSuspensePrimaryChildren(
2090
2091
primaryChildFragment . sibling = null ;
2091
2092
if ( currentFallbackChildFragment !== null ) {
2092
2093
// Delete the fallback child fragment
2093
- currentFallbackChildFragment . nextEffect = null ;
2094
- currentFallbackChildFragment . flags = Deletion ;
2095
- workInProgress . firstEffect = workInProgress . lastEffect = currentFallbackChildFragment ;
2094
+ const deletions = workInProgress . deletions ;
2095
+ if ( deletions === null ) {
2096
+ workInProgress . deletions = [ currentFallbackChildFragment ] ;
2097
+ // TODO (effects) Rename this to better reflect its new usage (e.g. ChildDeletions)
2098
+ workInProgress . flags |= Deletion ;
2099
+ } else {
2100
+ deletions . push ( currentFallbackChildFragment ) ;
2101
+ }
2096
2102
}
2097
2103
2098
2104
workInProgress . child = primaryChildFragment ;
@@ -2149,24 +2155,19 @@ function updateSuspenseFallbackChildren(
2149
2155
2150
2156
// The fallback fiber was added as a deletion effect during the first pass.
2151
2157
// However, since we're going to remain on the fallback, we no longer want
2152
- // to delete it. So we need to remove it from the list. Deletions are stored
2153
- // on the same list as effects. We want to keep the effects from the primary
2154
- // tree. So we copy the primary child fragment's effect list, which does not
2155
- // include the fallback deletion effect.
2156
- const progressedLastEffect = primaryChildFragment . lastEffect ;
2157
- if ( progressedLastEffect !== null ) {
2158
- workInProgress . firstEffect = primaryChildFragment . firstEffect ;
2159
- workInProgress . lastEffect = progressedLastEffect ;
2160
- progressedLastEffect . nextEffect = null ;
2161
- } else {
2162
- // TODO: Reset this somewhere else? Lol legacy mode is so weird.
2163
- workInProgress . firstEffect = workInProgress . lastEffect = null ;
2164
- }
2158
+ // to delete it.
2159
+ workInProgress . deletions = null ;
2165
2160
} else {
2166
2161
primaryChildFragment = createWorkInProgressOffscreenFiber (
2167
2162
currentPrimaryChildFragment ,
2168
2163
primaryChildProps ,
2169
2164
) ;
2165
+
2166
+ // Since we're reusing a current tree, we need to reuse the flags, too.
2167
+ // (We don't do this in legacy mode, because in legacy mode we don't re-use
2168
+ // the current tree; see previous branch.)
2169
+ primaryChildFragment . subtreeFlags =
2170
+ currentPrimaryChildFragment . subtreeFlags & StaticMask ;
2170
2171
}
2171
2172
let fallbackChildFragment ;
2172
2173
if ( currentFallbackChildFragment !== null ) {
@@ -2651,7 +2652,6 @@ function initSuspenseListRenderState(
2651
2652
tail : null | Fiber ,
2652
2653
lastContentRow : null | Fiber ,
2653
2654
tailMode : SuspenseListTailMode ,
2654
- lastEffectBeforeRendering : null | Fiber ,
2655
2655
) : void {
2656
2656
const renderState : null | SuspenseListRenderState =
2657
2657
workInProgress . memoizedState ;
@@ -2663,7 +2663,6 @@ function initSuspenseListRenderState(
2663
2663
last : lastContentRow ,
2664
2664
tail : tail ,
2665
2665
tailMode : tailMode ,
2666
- lastEffect : lastEffectBeforeRendering ,
2667
2666
} : SuspenseListRenderState ) ;
2668
2667
} else {
2669
2668
// We can reuse the existing object from previous renders.
@@ -2673,7 +2672,6 @@ function initSuspenseListRenderState(
2673
2672
renderState . last = lastContentRow ;
2674
2673
renderState . tail = tail ;
2675
2674
renderState . tailMode = tailMode ;
2676
- renderState . lastEffect = lastEffectBeforeRendering ;
2677
2675
}
2678
2676
}
2679
2677
@@ -2755,7 +2753,6 @@ function updateSuspenseListComponent(
2755
2753
tail ,
2756
2754
lastContentRow ,
2757
2755
tailMode ,
2758
- workInProgress . lastEffect ,
2759
2756
) ;
2760
2757
break ;
2761
2758
}
@@ -2787,7 +2784,6 @@ function updateSuspenseListComponent(
2787
2784
tail ,
2788
2785
null , // last
2789
2786
tailMode ,
2790
- workInProgress . lastEffect ,
2791
2787
) ;
2792
2788
break ;
2793
2789
}
@@ -2798,7 +2794,6 @@ function updateSuspenseListComponent(
2798
2794
null , // tail
2799
2795
null , // last
2800
2796
undefined ,
2801
- workInProgress . lastEffect ,
2802
2797
) ;
2803
2798
break ;
2804
2799
}
@@ -3058,15 +3053,14 @@ function remountFiber(
3058
3053
3059
3054
// Delete the old fiber and place the new one.
3060
3055
// Since the old fiber is disconnected, we have to schedule it manually.
3061
- const last = returnFiber . lastEffect ;
3062
- if ( last !== null ) {
3063
- last . nextEffect = current ;
3064
- returnFiber . lastEffect = current ;
3056
+ const deletions = returnFiber . deletions ;
3057
+ if ( deletions === null ) {
3058
+ returnFiber . deletions = [ current ] ;
3059
+ // TODO (effects) Rename this to better reflect its new usage (e.g. ChildDeletions)
3060
+ returnFiber . flags |= Deletion ;
3065
3061
} else {
3066
- returnFiber . firstEffect = returnFiber . lastEffect = current ;
3062
+ deletions . push ( current ) ;
3067
3063
}
3068
- current . nextEffect = null ;
3069
- current . flags = Deletion ;
3070
3064
3071
3065
newWorkInProgress . flags |= Placement ;
3072
3066
@@ -3151,15 +3145,6 @@ function beginWork(
3151
3145
}
3152
3146
case Profiler :
3153
3147
if ( enableProfilerTimer ) {
3154
- // Profiler should only call onRender when one of its descendants actually rendered.
3155
- const hasChildWork = includesSomeLane (
3156
- renderLanes ,
3157
- workInProgress . childLanes ,
3158
- ) ;
3159
- if ( hasChildWork ) {
3160
- workInProgress . flags |= Update ;
3161
- }
3162
-
3163
3148
// Reset effect durations for the next eventual effect phase.
3164
3149
// These are reset during render to allow the DevTools commit hook a chance to read them,
3165
3150
const stateNode = workInProgress . stateNode ;
@@ -3266,7 +3251,6 @@ function beginWork(
3266
3251
// update in the past but didn't complete it.
3267
3252
renderState . rendering = null ;
3268
3253
renderState . tail = null ;
3269
- renderState . lastEffect = null ;
3270
3254
}
3271
3255
pushSuspenseContext ( workInProgress , suspenseStackCursor . current ) ;
3272
3256
0 commit comments