Fix warning about setState in useEffect (#24295)

* Fix warning about setState in useEffect

* Fix test

* Fix multiple roots
This commit is contained in:
dan 2022-04-07 18:06:35 +01:00 committed by GitHub
parent 0579154772
commit d68b09defc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 8 deletions

View File

@ -396,9 +396,12 @@ let pendingPassiveEffectsRemainingLanes: Lanes = NoLanes;
const NESTED_UPDATE_LIMIT = 50;
let nestedUpdateCount: number = 0;
let rootWithNestedUpdates: FiberRoot | null = null;
let isFlushingPassiveEffects = false;
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
@ -522,6 +525,12 @@ export function scheduleUpdateOnFiber(
return null;
}
if (__DEV__) {
if (isFlushingPassiveEffects) {
didScheduleUpdateDuringPassiveEffects = true;
}
}
// Mark that the root has a pending update.
markRootUpdated(root, lane, eventTime);
@ -2204,6 +2213,10 @@ function commitRootImpl(
// There were no passive effects, so we can immediately release the cache
// pool for this render.
releaseRootPooledCache(root, remainingLanes);
if (__DEV__) {
nestedPassiveUpdateCount = 0;
rootWithPassiveNestedUpdates = null;
}
}
// Read this again, since an effect might have updated it
@ -2420,6 +2433,9 @@ function flushPassiveEffectsImpl() {
}
if (__DEV__) {
isFlushingPassiveEffects = true;
didScheduleUpdateDuringPassiveEffects = false;
if (enableDebugTracing) {
logPassiveEffectsStarted(lanes);
}
@ -2463,10 +2479,22 @@ function flushPassiveEffectsImpl() {
flushSyncCallbacks();
// If additional passive effects were scheduled, increment a counter. If this
// exceeds the limit, we'll fire a warning.
nestedPassiveUpdateCount =
rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
if (__DEV__) {
// If additional passive effects were scheduled, increment a counter. If this
// exceeds the limit, we'll fire a warning.
if (didScheduleUpdateDuringPassiveEffects) {
if (root === rootWithPassiveNestedUpdates) {
nestedPassiveUpdateCount++;
} else {
nestedPassiveUpdateCount = 0;
rootWithPassiveNestedUpdates = root;
}
} else {
nestedPassiveUpdateCount = 0;
}
isFlushingPassiveEffects = false;
didScheduleUpdateDuringPassiveEffects = false;
}
// TODO: Move to commitPassiveMountEffects
onPostCommitRootDevTools(root);
@ -2739,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 " +

View File

@ -396,9 +396,12 @@ let pendingPassiveEffectsRemainingLanes: Lanes = NoLanes;
const NESTED_UPDATE_LIMIT = 50;
let nestedUpdateCount: number = 0;
let rootWithNestedUpdates: FiberRoot | null = null;
let isFlushingPassiveEffects = false;
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
@ -522,6 +525,12 @@ export function scheduleUpdateOnFiber(
return null;
}
if (__DEV__) {
if (isFlushingPassiveEffects) {
didScheduleUpdateDuringPassiveEffects = true;
}
}
// Mark that the root has a pending update.
markRootUpdated(root, lane, eventTime);
@ -2204,6 +2213,10 @@ function commitRootImpl(
// There were no passive effects, so we can immediately release the cache
// pool for this render.
releaseRootPooledCache(root, remainingLanes);
if (__DEV__) {
nestedPassiveUpdateCount = 0;
rootWithPassiveNestedUpdates = null;
}
}
// Read this again, since an effect might have updated it
@ -2420,6 +2433,9 @@ function flushPassiveEffectsImpl() {
}
if (__DEV__) {
isFlushingPassiveEffects = true;
didScheduleUpdateDuringPassiveEffects = false;
if (enableDebugTracing) {
logPassiveEffectsStarted(lanes);
}
@ -2463,10 +2479,22 @@ function flushPassiveEffectsImpl() {
flushSyncCallbacks();
// If additional passive effects were scheduled, increment a counter. If this
// exceeds the limit, we'll fire a warning.
nestedPassiveUpdateCount =
rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
if (__DEV__) {
// If additional passive effects were scheduled, increment a counter. If this
// exceeds the limit, we'll fire a warning.
if (didScheduleUpdateDuringPassiveEffects) {
if (root === rootWithPassiveNestedUpdates) {
nestedPassiveUpdateCount++;
} else {
nestedPassiveUpdateCount = 0;
rootWithPassiveNestedUpdates = root;
}
} else {
nestedPassiveUpdateCount = 0;
}
isFlushingPassiveEffects = false;
didScheduleUpdateDuringPassiveEffects = false;
}
// TODO: Move to commitPassiveMountEffects
onPostCommitRootDevTools(root);
@ -2739,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 " +