diff --git a/packages/react-devtools-shared/src/__tests__/profilerContext-test.js b/packages/react-devtools-shared/src/__tests__/profilerContext-test.js index 35bc06e5891..a65b65e5b7c 100644 --- a/packages/react-devtools-shared/src/__tests__/profilerContext-test.js +++ b/packages/react-devtools-shared/src/__tests__/profilerContext-test.js @@ -337,18 +337,10 @@ describe('ProfilerContext', () => { await utils.actAsync(() => context.selectFiber(parentID, 'Parent')); expect(selectedElementID).toBe(parentID); - // We expect a "no element found" warning. - // Let's hide it from the test console though. - spyOn(console, 'warn'); - // Select an unmounted element and verify no Components tab selection doesn't change. await utils.actAsync(() => context.selectFiber(childID, 'Child')); expect(selectedElementID).toBe(parentID); - expect(console.warn).toHaveBeenCalledWith( - `No element found with id "${childID}"`, - ); - done(); }); }); diff --git a/packages/react-devtools-shared/src/__tests__/utils.js b/packages/react-devtools-shared/src/__tests__/utils.js index 0b3f03a7fb3..550ae111098 100644 --- a/packages/react-devtools-shared/src/__tests__/utils.js +++ b/packages/react-devtools-shared/src/__tests__/utils.js @@ -181,6 +181,7 @@ export function exportImportHelper(bridge: FrontendBridge, store: Store): void { expect(profilerStore.profilingData).not.toBeNull(); const profilingDataFrontendInitial = ((profilerStore.profilingData: any): ProfilingDataFrontend); + expect(profilingDataFrontendInitial.imported).toBe(false); const profilingDataExport = prepareProfilingDataExport( profilingDataFrontendInitial, @@ -197,15 +198,18 @@ export function exportImportHelper(bridge: FrontendBridge, store: Store): void { const profilingDataFrontend = prepareProfilingDataFrontendFromExport( (parsedProfilingDataExport: any), ); + expect(profilingDataFrontend.imported).toBe(true); // Sanity check that profiling snapshots are serialized correctly. - expect(profilingDataFrontendInitial).toEqual(profilingDataFrontend); + expect(profilingDataFrontendInitial.dataForRoots).toEqual( + profilingDataFrontend.dataForRoots, + ); // Snapshot the JSON-parsed object, rather than the raw string, because Jest formats the diff nicer. expect(parsedProfilingDataExport).toMatchSnapshot('imported data'); act(() => { - // Apply the new exported-then-reimported data so tests can re-run assertions. + // Apply the new exported-then-imported data so tests can re-run assertions. profilerStore.profilingData = profilingDataFrontend; }); } diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/ProfilerContext.js b/packages/react-devtools-shared/src/devtools/views/Profiler/ProfilerContext.js index 1108a6bb64f..ac3b58f1879 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/ProfilerContext.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/ProfilerContext.js @@ -138,12 +138,16 @@ function ProfilerContextController({children}: Props) { selectFiberName(name); // Sync selection to the Components tab for convenience. - if (id !== null) { - const element = store.getElementByID(id); - - // Keep in mind that profiling data may be from a previous session. - // In that case, IDs may match up arbitrarily; to be safe, compare both ID and display name. - if (element !== null && element.displayName === name) { + // Keep in mind that profiling data may be from a previous session. + // If data has been imported, we should skip the selection sync. + if ( + id !== null && + profilingData !== null && + profilingData.imported === false + ) { + // We should still check to see if this element is still in the store. + // It may have been removed during profiling. + if (store.containsElement(id)) { dispatch({ type: 'SELECT_ELEMENT_BY_ID', payload: id, @@ -151,7 +155,7 @@ function ProfilerContextController({children}: Props) { } } }, - [dispatch, selectFiberID, selectFiberName, store], + [dispatch, selectFiberID, selectFiberName, store, profilingData], ); const setRootIDAndClearFiber = useCallback( diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/types.js b/packages/react-devtools-shared/src/devtools/views/Profiler/types.js index 4156aa592c4..ab63f093ed2 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/types.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/types.js @@ -105,6 +105,7 @@ export type ProfilingDataForRootFrontend = {| export type ProfilingDataFrontend = {| // Profiling data per root. dataForRoots: Map, + imported: boolean, |}; export type CommitDataExport = {| diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/utils.js b/packages/react-devtools-shared/src/devtools/views/Profiler/utils.js index c453fc166cf..9691af89a58 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/utils.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/utils.js @@ -99,7 +99,7 @@ export function prepareProfilingDataFrontendFromBackendAndStore( ); }); - return {dataForRoots}; + return {dataForRoots, imported: false}; } // Converts a Profiling data export into the format required by the Store. @@ -156,7 +156,7 @@ export function prepareProfilingDataFrontendFromExport( }, ); - return {dataForRoots}; + return {dataForRoots, imported: true}; } // Converts a Store Profiling data into a format that can be safely (JSON) serialized for export.