diff --git a/packages/react-devtools-shared/src/__tests__/treeContext-test.js b/packages/react-devtools-shared/src/__tests__/treeContext-test.js
index 0db248c017861..30d21c0335ddb 100644
--- a/packages/react-devtools-shared/src/__tests__/treeContext-test.js
+++ b/packages/react-devtools-shared/src/__tests__/treeContext-test.js
@@ -2119,6 +2119,64 @@ describe('TreeListContext', () => {
`);
});
+ it('should update correctly when elements are added/removed', () => {
+ const container = document.createElement('div');
+ let errored = false;
+ function ErrorOnce() {
+ if (!errored) {
+ errored = true;
+ console.error('test-only:one-time-error');
+ }
+ return null;
+ }
+ withErrorsOrWarningsIgnored(['test-only:'], () =>
+ utils.act(() =>
+ legacyRender(
+
+
+ ,
+ container,
+ ),
+ ),
+ );
+
+ let renderer;
+ utils.act(() => (renderer = TestRenderer.create()));
+ expect(state).toMatchInlineSnapshot(`
+ ✕ 1, ⚠ 0
+ [root]
+ ✕
+ `);
+
+ withErrorsOrWarningsIgnored(['test-only:'], () =>
+ utils.act(() =>
+ legacyRender(
+
+
+
+ ,
+ container,
+ ),
+ ),
+ );
+
+ utils.act(() => renderer.update());
+ expect(state).toMatchInlineSnapshot(`
+ ✕ 1, ⚠ 0
+ [root]
+
+ ✕
+ `);
+
+ selectNextErrorOrWarning();
+ expect(state).toMatchInlineSnapshot(`
+ ✕ 1, ⚠ 0
+ [root]
+
+ → ✕
+ `);
+ });
+
it('should update select and auto-expand parts components within hidden parts of the tree', () => {
const Wrapper = ({children}) => children;
diff --git a/packages/react-devtools-shared/src/devtools/store.js b/packages/react-devtools-shared/src/devtools/store.js
index 16bc56ae64f07..7cd5c41e8b0d7 100644
--- a/packages/react-devtools-shared/src/devtools/store.js
+++ b/packages/react-devtools-shared/src/devtools/store.js
@@ -1187,6 +1187,18 @@ export default class Store extends EventEmitter<{|
console.groupEnd();
}
+ const indicesOfCachedErrorsOrWarningsAreStale =
+ !haveErrorsOrWarningsChanged &&
+ (addedElementIDs.length > 0 || removedElementIDs.size > 0);
+ if (indicesOfCachedErrorsOrWarningsAreStale) {
+ this._cachedErrorAndWarningTuples.forEach(entry => {
+ const index = this.getIndexOfElementID(entry.id);
+ if (index !== null) {
+ entry.index = index;
+ }
+ });
+ }
+
this.emit('mutated', [addedElementIDs, removedElementIDs]);
};