@@ -1138,7 +1138,7 @@ export function attach(
11381138 // if any passive effects called console.warn / console.error.
11391139 let needsToFlushComponentLogs = false;
11401140
1141- function bruteForceFlushErrorsAndWarnings() {
1141+ function bruteForceFlushErrorsAndWarnings(root: FiberInstance ) {
11421142 // Refresh error/warning count for all mounted unfiltered Fibers.
11431143 let hasChanges = false;
11441144 // eslint-disable-next-line no-for-of-loops/no-for-of-loops
@@ -1156,7 +1156,7 @@ export function attach(
11561156 }
11571157 }
11581158 if (hasChanges) {
1159- flushPendingEvents();
1159+ flushPendingEvents(root );
11601160 }
11611161 }
11621162
@@ -1183,7 +1183,7 @@ export function attach(
11831183 updateMostRecentlyInspectedElementIfNecessary(devtoolsInstance.id);
11841184 }
11851185 }
1186- flushPendingEvents();
1186+ flushPendingEvents(null );
11871187 }
11881188
11891189 function clearConsoleLogsHelper(instanceID: number, type: 'error' | 'warn') {
@@ -1211,7 +1211,7 @@ export function attach(
12111211 }
12121212 const changed = recordConsoleLogs(devtoolsInstance, componentLogsEntry);
12131213 if (changed) {
1214- flushPendingEvents();
1214+ flushPendingEvents(null );
12151215 updateMostRecentlyInspectedElementIfNecessary(devtoolsInstance.id);
12161216 }
12171217 }
@@ -1533,6 +1533,8 @@ export function attach(
15331533 if (isProfiling) {
15341534 // Re-mounting a tree while profiling is in progress might break a lot of assumptions.
15351535 // If necessary, we could support this- but it doesn't seem like a necessary use case.
1536+ // Supporting change of filters while profiling would require a refactor
1537+ // to flush after each root instead of at the end.
15361538 throw Error('Cannot modify filter preferences while profiling');
15371539 }
15381540
@@ -1647,7 +1649,8 @@ export function attach(
16471649 focusedActivityFilter.activityID = focusedActivityID;
16481650 }
16491651
1650- flushPendingEvents();
1652+ // We're not profiling so it's safe to flush without a specific root.
1653+ flushPendingEvents(null);
16511654
16521655 needsToFlushComponentLogs = false;
16531656 }
@@ -2203,7 +2206,12 @@ export function attach(
22032206 }
22042207 }
22052208
2206- function flushPendingEvents(): void {
2209+ /**
2210+ * Allowed to flush pending events without a specific root when:
2211+ * - pending operations don't record tree mutations e.g. TREE_OPERATION_UPDATE_ERRORS_OR_WARNINGS
2212+ * - not profiling (the commit tree builder requires the root of the mutations)
2213+ */
2214+ function flushPendingEvents(root: FiberInstance | null): void {
22072215 if (shouldBailoutWithPendingOperations()) {
22082216 // If we aren't profiling, we can just bail out here.
22092217 // No use sending an empty update over the bridge.
@@ -2245,11 +2253,10 @@ export function attach(
22452253 // Which in turn enables fiber props, states, and hooks to be inspected.
22462254 let i = 0;
22472255 operations[i++] = rendererID;
2248- if (currentRoot === null) {
2249- // TODO: This is not always safe so this field is probably not needed.
2256+ if (root === null) {
22502257 operations[i++] = -1;
22512258 } else {
2252- operations[i++] = currentRoot .id;
2259+ operations[i++] = root .id;
22532260 }
22542261
22552262 // Now fill in the string table.
@@ -5746,11 +5753,11 @@ export function attach(
57465753
57475754 mountFiberRecursively(root.current, false);
57485755
5756+ flushPendingEvents(currentRoot);
5757+
57495758 currentRoot = (null: any);
57505759 });
57515760
5752- flushPendingEvents();
5753-
57545761 needsToFlushComponentLogs = false;
57555762 }
57565763 }
@@ -5760,7 +5767,7 @@ export function attach(
57605767 // safe to stop calling it from Fiber.
57615768 }
57625769
5763- function handlePostCommitFiberRoot(root: any ) {
5770+ function handlePostCommitFiberRoot(root: FiberRoot ) {
57645771 if (isProfiling && rootSupportsProfiling(root)) {
57655772 if (currentCommitProfilingMetadata !== null) {
57665773 const {effectDuration, passiveEffectDuration} =
@@ -5774,12 +5781,18 @@ export function attach(
57745781 }
57755782
57765783 if (needsToFlushComponentLogs) {
5784+ const rootInstance = rootToFiberInstanceMap.get(root);
5785+ if (rootInstance === undefined) {
5786+ throw new Error(
5787+ 'Should have a root instance for a committed root. This is a bug in React DevTools.',
5788+ );
5789+ }
57775790 // We received new logs after commit. I.e. in a passive effect. We need to
57785791 // traverse the tree to find the affected ones. If we just moved the whole
57795792 // tree traversal from handleCommitFiberRoot to handlePostCommitFiberRoot
57805793 // this wouldn't be needed. For now we just brute force check all instances.
57815794 // This is not that common of a case.
5782- bruteForceFlushErrorsAndWarnings();
5795+ bruteForceFlushErrorsAndWarnings(rootInstance );
57835796 }
57845797 }
57855798
@@ -5876,7 +5889,7 @@ export function attach(
58765889 }
58775890
58785891 // We're done here.
5879- flushPendingEvents();
5892+ flushPendingEvents(currentRoot );
58805893
58815894 needsToFlushComponentLogs = false;
58825895
0 commit comments