File tree Expand file tree Collapse file tree 5 files changed +27
-8
lines changed
packages/react-reconciler/src Expand file tree Collapse file tree 5 files changed +27
-8
lines changed Original file line number Diff line number Diff line change @@ -19,7 +19,10 @@ import type {
1919import type { Lane , Lanes } from './ReactFiberLane.new' ;
2020import type { OffscreenInstance } from './ReactFiberOffscreenComponent' ;
2121
22- import { warnAboutUpdateOnNotYetMountedFiberInDEV } from './ReactFiberWorkLoop.new' ;
22+ import {
23+ warnAboutUpdateOnNotYetMountedFiberInDEV ,
24+ throwIfInfiniteUpdateLoopDetected ,
25+ } from './ReactFiberWorkLoop.new' ;
2326import {
2427 NoLane ,
2528 NoLanes ,
@@ -207,6 +210,13 @@ function markUpdateLaneFromFiberToRoot(
207210}
208211
209212function 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+
210220 // When a setState happens, we must ensure the root is scheduled. Because
211221 // update queues do not have a backpointer to the root, the only way to do
212222 // 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 {
1818} from './ReactFiberClassUpdateQueue.old' ;
1919import type { Lane } from './ReactFiberLane.old' ;
2020
21- import { warnAboutUpdateOnNotYetMountedFiberInDEV } from './ReactFiberWorkLoop.old' ;
21+ import {
22+ warnAboutUpdateOnNotYetMountedFiberInDEV ,
23+ throwIfInfiniteUpdateLoopDetected ,
24+ } from './ReactFiberWorkLoop.old' ;
2225import { mergeLanes } from './ReactFiberLane.old' ;
2326import { NoFlags , Placement , Hydrating } from './ReactFiberFlags' ;
2427import { HostRoot } from './ReactWorkTags' ;
@@ -143,6 +146,13 @@ function markUpdateLaneFromFiberToRoot(
143146 sourceFiber : Fiber ,
144147 lane : Lane ,
145148) : 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+
146156 // Update the source fiber's lanes
147157 sourceFiber . lanes = mergeLanes ( sourceFiber . lanes , lane ) ;
148158 let alternate = sourceFiber . alternate ;
Original file line number Diff line number Diff line change @@ -536,8 +536,6 @@ export function scheduleUpdateOnFiber(
536536 lane : Lane ,
537537 eventTime : number ,
538538) {
539- checkForNestedUpdates ( ) ;
540-
541539 if ( __DEV__ ) {
542540 if ( isRunningInsertionEffect ) {
543541 console . error ( 'useInsertionEffect must not schedule updates.' ) ;
@@ -2782,10 +2780,12 @@ function jnd(timeElapsed: number) {
27822780 : ceil ( timeElapsed / 1960 ) * 1960 ;
27832781}
27842782
2785- function checkForNestedUpdates ( ) {
2783+ export function throwIfInfiniteUpdateLoopDetected ( ) {
27862784 if ( nestedUpdateCount > NESTED_UPDATE_LIMIT ) {
27872785 nestedUpdateCount = 0 ;
2786+ nestedPassiveUpdateCount = 0 ;
27882787 rootWithNestedUpdates = null ;
2788+ rootWithPassiveNestedUpdates = null ;
27892789
27902790 throw new Error (
27912791 '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(
531531 lane : Lane ,
532532 eventTime : number ,
533533) {
534- checkForNestedUpdates ( ) ;
535-
536534 if ( __DEV__ ) {
537535 if ( isRunningInsertionEffect ) {
538536 console . error ( 'useInsertionEffect must not schedule updates.' ) ;
@@ -2771,7 +2769,7 @@ function jnd(timeElapsed: number) {
27712769 : ceil ( timeElapsed / 1960 ) * 1960 ;
27722770}
27732771
2774- function checkForNestedUpdates ( ) {
2772+ export function throwIfInfiniteUpdateLoopDetected ( ) {
27752773 if ( nestedUpdateCount > NESTED_UPDATE_LIMIT ) {
27762774 nestedUpdateCount = 0 ;
27772775 rootWithNestedUpdates = null ;
Original file line number Diff line number Diff line change 1+ 58bb11764bf0bb6db47527a64f693f67cdd3b0bb [FORKED] Check for infinite update loops even if unmounted
1231882b5dd66f34f70d341ea2781cacbe802bf4d5 [FORKED] Bugfix: Revealing a hidden update
2317691acc071d56261d43c3cf183f287d983baa9b [FORKED] Don't update childLanes until after current render
You can’t perform that action at this time.
0 commit comments