File tree 5 files changed +27
-8
lines changed
packages/react-reconciler/src
5 files changed +27
-8
lines changed Original file line number Diff line number Diff line change @@ -19,7 +19,10 @@ import type {
19
19
import type { Lane , Lanes } from './ReactFiberLane.new' ;
20
20
import type { OffscreenInstance } from './ReactFiberOffscreenComponent' ;
21
21
22
- import { warnAboutUpdateOnNotYetMountedFiberInDEV } from './ReactFiberWorkLoop.new' ;
22
+ import {
23
+ warnAboutUpdateOnNotYetMountedFiberInDEV ,
24
+ throwIfInfiniteUpdateLoopDetected ,
25
+ } from './ReactFiberWorkLoop.new' ;
23
26
import {
24
27
NoLane ,
25
28
NoLanes ,
@@ -207,6 +210,13 @@ function markUpdateLaneFromFiberToRoot(
207
210
}
208
211
209
212
function getRootForUpdatedFiber ( sourceFiber : Fiber ) : FiberRoot | null {
213
+ // TODO: We will detect and infinite update loop and throw even if this fiber
214
+ // has already unmounted. This isn't really necessary but it happens to be the
215
+ // current behavior we've used for several release cycles. Consider not
216
+ // performing this check if the updated fiber already unmounted, since it's
217
+ // not possible for that to cause an infinite update loop.
218
+ throwIfInfiniteUpdateLoopDetected ( ) ;
219
+
210
220
// When a setState happens, we must ensure the root is scheduled. Because
211
221
// update queues do not have a backpointer to the root, the only way to do
212
222
// this currently is to walk up the return path. This used to not be a big
Original file line number Diff line number Diff line change @@ -18,7 +18,10 @@ import type {
18
18
} from './ReactFiberClassUpdateQueue.old' ;
19
19
import type { Lane } from './ReactFiberLane.old' ;
20
20
21
- import { warnAboutUpdateOnNotYetMountedFiberInDEV } from './ReactFiberWorkLoop.old' ;
21
+ import {
22
+ warnAboutUpdateOnNotYetMountedFiberInDEV ,
23
+ throwIfInfiniteUpdateLoopDetected ,
24
+ } from './ReactFiberWorkLoop.old' ;
22
25
import { mergeLanes } from './ReactFiberLane.old' ;
23
26
import { NoFlags , Placement , Hydrating } from './ReactFiberFlags' ;
24
27
import { HostRoot } from './ReactWorkTags' ;
@@ -143,6 +146,13 @@ function markUpdateLaneFromFiberToRoot(
143
146
sourceFiber : Fiber ,
144
147
lane : Lane ,
145
148
) : FiberRoot | null {
149
+ // TODO: We will detect and infinite update loop and throw even if this fiber
150
+ // has already unmounted. This isn't really necessary but it happens to be the
151
+ // current behavior we've used for several release cycles. Consider not
152
+ // performing this check if the updated fiber already unmounted, since it's
153
+ // not possible for that to cause an infinite update loop.
154
+ throwIfInfiniteUpdateLoopDetected ( ) ;
155
+
146
156
// Update the source fiber's lanes
147
157
sourceFiber . lanes = mergeLanes ( sourceFiber . lanes , lane ) ;
148
158
let alternate = sourceFiber . alternate ;
Original file line number Diff line number Diff line change @@ -536,8 +536,6 @@ export function scheduleUpdateOnFiber(
536
536
lane : Lane ,
537
537
eventTime : number ,
538
538
) {
539
- checkForNestedUpdates ( ) ;
540
-
541
539
if ( __DEV__ ) {
542
540
if ( isRunningInsertionEffect ) {
543
541
console . error ( 'useInsertionEffect must not schedule updates.' ) ;
@@ -2782,10 +2780,12 @@ function jnd(timeElapsed: number) {
2782
2780
: ceil ( timeElapsed / 1960 ) * 1960 ;
2783
2781
}
2784
2782
2785
- function checkForNestedUpdates ( ) {
2783
+ export function throwIfInfiniteUpdateLoopDetected ( ) {
2786
2784
if ( nestedUpdateCount > NESTED_UPDATE_LIMIT ) {
2787
2785
nestedUpdateCount = 0 ;
2786
+ nestedPassiveUpdateCount = 0 ;
2788
2787
rootWithNestedUpdates = null ;
2788
+ rootWithPassiveNestedUpdates = null ;
2789
2789
2790
2790
throw new Error (
2791
2791
'Maximum update depth exceeded. This can happen when a component ' +
Original file line number Diff line number Diff line change @@ -531,8 +531,6 @@ export function scheduleUpdateOnFiber(
531
531
lane : Lane ,
532
532
eventTime : number ,
533
533
) {
534
- checkForNestedUpdates ( ) ;
535
-
536
534
if ( __DEV__ ) {
537
535
if ( isRunningInsertionEffect ) {
538
536
console . error ( 'useInsertionEffect must not schedule updates.' ) ;
@@ -2771,7 +2769,7 @@ function jnd(timeElapsed: number) {
2771
2769
: ceil ( timeElapsed / 1960 ) * 1960 ;
2772
2770
}
2773
2771
2774
- function checkForNestedUpdates ( ) {
2772
+ export function throwIfInfiniteUpdateLoopDetected ( ) {
2775
2773
if ( nestedUpdateCount > NESTED_UPDATE_LIMIT ) {
2776
2774
nestedUpdateCount = 0 ;
2777
2775
rootWithNestedUpdates = null ;
Original file line number Diff line number Diff line change
1
+ 58bb11764bf0bb6db47527a64f693f67cdd3b0bb [FORKED] Check for infinite update loops even if unmounted
1
2
31882b5dd66f34f70d341ea2781cacbe802bf4d5 [FORKED] Bugfix: Revealing a hidden update
2
3
17691acc071d56261d43c3cf183f287d983baa9b [FORKED] Don't update childLanes until after current render
You can’t perform that action at this time.
0 commit comments