diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index 78dd996ecfd3f..3f4071164df57 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -401,6 +401,7 @@ let didScheduleUpdateDuringPassiveEffects = false; const NESTED_PASSIVE_UPDATE_LIMIT = 50; let nestedPassiveUpdateCount: number = 0; +let rootWithPassiveNestedUpdates: FiberRoot | null = null; // If two updates are scheduled within the same event, we should treat their // event times as simultaneous, even if the actual clock time has advanced @@ -2214,6 +2215,7 @@ function commitRootImpl( releaseRootPooledCache(root, remainingLanes); if (__DEV__) { nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; } } @@ -2481,7 +2483,12 @@ function flushPassiveEffectsImpl() { // If additional passive effects were scheduled, increment a counter. If this // exceeds the limit, we'll fire a warning. if (didScheduleUpdateDuringPassiveEffects) { - nestedPassiveUpdateCount++; + if (root === rootWithPassiveNestedUpdates) { + nestedPassiveUpdateCount++; + } else { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = root; + } } else { nestedPassiveUpdateCount = 0; } @@ -2760,6 +2767,8 @@ function checkForNestedUpdates() { if (__DEV__) { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; + console.error( 'Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index fd9ab04904532..604a585406ae6 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -401,6 +401,7 @@ let didScheduleUpdateDuringPassiveEffects = false; const NESTED_PASSIVE_UPDATE_LIMIT = 50; let nestedPassiveUpdateCount: number = 0; +let rootWithPassiveNestedUpdates: FiberRoot | null = null; // If two updates are scheduled within the same event, we should treat their // event times as simultaneous, even if the actual clock time has advanced @@ -2214,6 +2215,7 @@ function commitRootImpl( releaseRootPooledCache(root, remainingLanes); if (__DEV__) { nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; } } @@ -2481,7 +2483,12 @@ function flushPassiveEffectsImpl() { // If additional passive effects were scheduled, increment a counter. If this // exceeds the limit, we'll fire a warning. if (didScheduleUpdateDuringPassiveEffects) { - nestedPassiveUpdateCount++; + if (root === rootWithPassiveNestedUpdates) { + nestedPassiveUpdateCount++; + } else { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = root; + } } else { nestedPassiveUpdateCount = 0; } @@ -2760,6 +2767,8 @@ function checkForNestedUpdates() { if (__DEV__) { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; + console.error( 'Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + diff --git a/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShared-test.js b/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShared-test.js index 97dc89ac4a805..d74553eb9959d 100644 --- a/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShared-test.js +++ b/packages/use-sync-external-store/src/__tests__/useSyncExternalStoreShared-test.js @@ -584,16 +584,9 @@ describe('Shared useSyncExternalStore behavior (shim and built-in)', () => { 'calls setState inside componentWillUpdate or componentDidUpdate. React limits ' + 'the number of nested updates to prevent infinite loops.', ); - }).toErrorDev( - gate(flags => flags.enableUseSyncExternalStoreShim) - ? [ - 'The result of getSnapshot should be cached to avoid an infinite loop', - ] - : [ - 'Maximum update depth exceeded.', - 'The result of getSnapshot should be cached to avoid an infinite loop', - ], - ); + }).toErrorDev([ + 'The result of getSnapshot should be cached to avoid an infinite loop', + ]); }); test('getSnapshot can return NaN without infinite loop warning', async () => {