@samitouri / QOS-React / commits / d68b09defc

Fix warning about setState in useEffect (#24295)

* Fix warning about setState in useEffect * Fix test * Fix multiple roots

dan committed Apr 7, 2022 at 18:06 UTC d68b09defca37c30d3a7a34d4de884e374c74858
2 files changed +68 -8
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+34 -4
@@ -396,9 +396,12 @@ let pendingPassiveEffectsRemainingLanes: Lanes = NoLanes;
396 const NESTED_UPDATE_LIMIT = 50;
397 let nestedUpdateCount: number = 0;
398 let rootWithNestedUpdates: FiberRoot | null = null;
399 +let isFlushingPassiveEffects = false;
400 +let didScheduleUpdateDuringPassiveEffects = false;
401
402 const NESTED_PASSIVE_UPDATE_LIMIT = 50;
403 let nestedPassiveUpdateCount: number = 0;
404 +let rootWithPassiveNestedUpdates: FiberRoot | null = null;
405
406 // If two updates are scheduled within the same event, we should treat their
407 // event times as simultaneous, even if the actual clock time has advanced
@@ -522,6 +525,12 @@ export function scheduleUpdateOnFiber(
525 return null;
526 }
527
528 + if (__DEV__) {
529 + if (isFlushingPassiveEffects) {
530 + didScheduleUpdateDuringPassiveEffects = true;
531 + }
532 + }
533 +
534 // Mark that the root has a pending update.
535 markRootUpdated(root, lane, eventTime);
536
@@ -2204,6 +2213,10 @@ function commitRootImpl(
2213 // There were no passive effects, so we can immediately release the cache
2214 // pool for this render.
2215 releaseRootPooledCache(root, remainingLanes);
2216 + if (__DEV__) {
2217 + nestedPassiveUpdateCount = 0;
2218 + rootWithPassiveNestedUpdates = null;
2219 + }
2220 }
2221
2222 // Read this again, since an effect might have updated it
@@ -2420,6 +2433,9 @@ function flushPassiveEffectsImpl() {
2433 }
2434
2435 if (__DEV__) {
2436 + isFlushingPassiveEffects = true;
2437 + didScheduleUpdateDuringPassiveEffects = false;
2438 +
2439 if (enableDebugTracing) {
2440 logPassiveEffectsStarted(lanes);
2441 }
@@ -2463,10 +2479,22 @@ function flushPassiveEffectsImpl() {
2479
2480 flushSyncCallbacks();
2481
2466 - // If additional passive effects were scheduled, increment a counter. If this
2467 - // exceeds the limit, we'll fire a warning.
2468 - nestedPassiveUpdateCount =
2469 - rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
2482 + if (__DEV__) {
2483 + // If additional passive effects were scheduled, increment a counter. If this
2484 + // exceeds the limit, we'll fire a warning.
2485 + if (didScheduleUpdateDuringPassiveEffects) {
2486 + if (root === rootWithPassiveNestedUpdates) {
2487 + nestedPassiveUpdateCount++;
2488 + } else {
2489 + nestedPassiveUpdateCount = 0;
2490 + rootWithPassiveNestedUpdates = root;
2491 + }
2492 + } else {
2493 + nestedPassiveUpdateCount = 0;
2494 + }
2495 + isFlushingPassiveEffects = false;
2496 + didScheduleUpdateDuringPassiveEffects = false;
2497 + }
2498
2499 // TODO: Move to commitPassiveMountEffects
2500 onPostCommitRootDevTools(root);
@@ -2739,6 +2767,8 @@ function checkForNestedUpdates() {
2767 if (__DEV__) {
2768 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
2769 nestedPassiveUpdateCount = 0;
2770 + rootWithPassiveNestedUpdates = null;
2771 +
2772 console.error(
2773 'Maximum update depth exceeded. This can happen when a component ' +
2774 "calls setState inside useEffect, but useEffect either doesn't " +
packages/react-reconciler/src/ReactFiberWorkLoop.old.js
+34 -4
@@ -396,9 +396,12 @@ let pendingPassiveEffectsRemainingLanes: Lanes = NoLanes;
396 const NESTED_UPDATE_LIMIT = 50;
397 let nestedUpdateCount: number = 0;
398 let rootWithNestedUpdates: FiberRoot | null = null;
399 +let isFlushingPassiveEffects = false;
400 +let didScheduleUpdateDuringPassiveEffects = false;
401
402 const NESTED_PASSIVE_UPDATE_LIMIT = 50;
403 let nestedPassiveUpdateCount: number = 0;
404 +let rootWithPassiveNestedUpdates: FiberRoot | null = null;
405
406 // If two updates are scheduled within the same event, we should treat their
407 // event times as simultaneous, even if the actual clock time has advanced
@@ -522,6 +525,12 @@ export function scheduleUpdateOnFiber(
525 return null;
526 }
527
528 + if (__DEV__) {
529 + if (isFlushingPassiveEffects) {
530 + didScheduleUpdateDuringPassiveEffects = true;
531 + }
532 + }
533 +
534 // Mark that the root has a pending update.
535 markRootUpdated(root, lane, eventTime);
536
@@ -2204,6 +2213,10 @@ function commitRootImpl(
2213 // There were no passive effects, so we can immediately release the cache
2214 // pool for this render.
2215 releaseRootPooledCache(root, remainingLanes);
2216 + if (__DEV__) {
2217 + nestedPassiveUpdateCount = 0;
2218 + rootWithPassiveNestedUpdates = null;
2219 + }
2220 }
2221
2222 // Read this again, since an effect might have updated it
@@ -2420,6 +2433,9 @@ function flushPassiveEffectsImpl() {
2433 }
2434
2435 if (__DEV__) {
2436 + isFlushingPassiveEffects = true;
2437 + didScheduleUpdateDuringPassiveEffects = false;
2438 +
2439 if (enableDebugTracing) {
2440 logPassiveEffectsStarted(lanes);
2441 }
@@ -2463,10 +2479,22 @@ function flushPassiveEffectsImpl() {
2479
2480 flushSyncCallbacks();
2481
2466 - // If additional passive effects were scheduled, increment a counter. If this
2467 - // exceeds the limit, we'll fire a warning.
2468 - nestedPassiveUpdateCount =
2469 - rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
2482 + if (__DEV__) {
2483 + // If additional passive effects were scheduled, increment a counter. If this
2484 + // exceeds the limit, we'll fire a warning.
2485 + if (didScheduleUpdateDuringPassiveEffects) {
2486 + if (root === rootWithPassiveNestedUpdates) {
2487 + nestedPassiveUpdateCount++;
2488 + } else {
2489 + nestedPassiveUpdateCount = 0;
2490 + rootWithPassiveNestedUpdates = root;
2491 + }
2492 + } else {
2493 + nestedPassiveUpdateCount = 0;
2494 + }
2495 + isFlushingPassiveEffects = false;
2496 + didScheduleUpdateDuringPassiveEffects = false;
2497 + }
2498
2499 // TODO: Move to commitPassiveMountEffects
2500 onPostCommitRootDevTools(root);
@@ -2739,6 +2767,8 @@ function checkForNestedUpdates() {
2767 if (__DEV__) {
2768 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
2769 nestedPassiveUpdateCount = 0;
2770 + rootWithPassiveNestedUpdates = null;
2771 +
2772 console.error(
2773 'Maximum update depth exceeded. This can happen when a component ' +
2774 "calls setState inside useEffect, but useEffect either doesn't " +