diff --git a/src/devtools/views/Profiler/Profiler.js b/src/devtools/views/Profiler/Profiler.js
index a4a5ce935fd88..581157eb11aa6 100644
--- a/src/devtools/views/Profiler/Profiler.js
+++ b/src/devtools/views/Profiler/Profiler.js
@@ -28,6 +28,7 @@ function Profiler(_: {||}) {
didRecordCommits,
isProcessingData,
isProfiling,
+ selectedCommitIndex,
selectedFiberID,
selectedTabID,
selectTab,
@@ -67,10 +68,18 @@ function Profiler(_: {||}) {
break;
case 'flame-chart':
case 'ranked-chart':
- if (selectedFiberID !== null) {
- sidebar = ;
- } else {
- sidebar = ;
+ // TRICKY
+ // Handle edge case where no commit is selected because of a min-duration filter update.
+ // In that case, the selected commit index would be null.
+ // We could still show a sidebar for the previously selected fiber,
+ // but it would be an odd user experience.
+ // TODO (ProfilerContext) This check should not be necessary.
+ if (selectedCommitIndex !== null) {
+ if (selectedFiberID !== null) {
+ sidebar = ;
+ } else {
+ sidebar = ;
+ }
}
break;
default:
diff --git a/src/devtools/views/Profiler/ProfilerContext.js b/src/devtools/views/Profiler/ProfilerContext.js
index f50947e1cf778..dffbbf6659ab4 100644
--- a/src/devtools/views/Profiler/ProfilerContext.js
+++ b/src/devtools/views/Profiler/ProfilerContext.js
@@ -127,28 +127,32 @@ function ProfilerContextController({ children }: Props) {
const [rootID, setRootID] = useState(null);
if (prevProfilingData !== profilingData) {
- setPrevProfilingData(profilingData);
-
- const dataForRoots =
- profilingData !== null ? profilingData.dataForRoots : null;
- if (dataForRoots != null) {
- const firstRootID = dataForRoots.keys().next().value || null;
-
- if (rootID === null || !dataForRoots.has(rootID)) {
- let selectedElementRootID = null;
- if (selectedElementID !== null) {
- selectedElementRootID = store.getRootIDForElement(selectedElementID);
- }
- if (
- selectedElementRootID !== null &&
- dataForRoots.has(selectedElementRootID)
- ) {
- setRootID(selectedElementRootID);
- } else {
- setRootID(firstRootID);
+ batchedUpdates(() => {
+ setPrevProfilingData(profilingData);
+
+ const dataForRoots =
+ profilingData !== null ? profilingData.dataForRoots : null;
+ if (dataForRoots != null) {
+ const firstRootID = dataForRoots.keys().next().value || null;
+
+ if (rootID === null || !dataForRoots.has(rootID)) {
+ let selectedElementRootID = null;
+ if (selectedElementID !== null) {
+ selectedElementRootID = store.getRootIDForElement(
+ selectedElementID
+ );
+ }
+ if (
+ selectedElementRootID !== null &&
+ dataForRoots.has(selectedElementRootID)
+ ) {
+ setRootID(selectedElementRootID);
+ } else {
+ setRootID(firstRootID);
+ }
}
}
- }
+ });
}
const startProfiling = useCallback(
diff --git a/src/devtools/views/Profiler/SidebarSelectedFiberInfo.js b/src/devtools/views/Profiler/SidebarSelectedFiberInfo.js
index 9a34361a173c8..64def785e2a2d 100644
--- a/src/devtools/views/Profiler/SidebarSelectedFiberInfo.js
+++ b/src/devtools/views/Profiler/SidebarSelectedFiberInfo.js
@@ -89,7 +89,7 @@ export default function SidebarSelectedFiberInfo(_: Props) {
}
type WhatChangedProps = {|
- commitIndex: number,
+ commitIndex: number | null,
fiberID: number,
profilerStore: ProfilerStore,
rootID: number,
@@ -101,6 +101,14 @@ function WhatChanged({
profilerStore,
rootID,
}: WhatChangedProps) {
+ // TRICKY
+ // Handle edge case where no commit is selected because of a min-duration filter update.
+ // If the commit index is null, suspending for data below would throw an error.
+ // TODO (ProfilerContext) This check should not be necessary.
+ if (commitIndex === null) {
+ return null;
+ }
+
const { changeDescriptions } = profilerStore.getCommitData(
((rootID: any): number),
commitIndex
diff --git a/src/devtools/views/Profiler/SnapshotSelector.js b/src/devtools/views/Profiler/SnapshotSelector.js
index a41187d89d08a..8ffca5cb65f9a 100644
--- a/src/devtools/views/Profiler/SnapshotSelector.js
+++ b/src/devtools/views/Profiler/SnapshotSelector.js
@@ -59,7 +59,7 @@ export default function SnapshotSelector(_: Props) {
return null;
}, [filteredCommitIndices, selectedCommitIndex]);
- // TODO (profiling) This should be managed by the context controller (reducer).
+ // TODO (ProfilerContext) This should be managed by the context controller (reducer).
// It doesn't currently know about the filtered commits though (since it doesn't suspend).
// Maybe this component should pass filteredCommitIndices up?
if (selectedFilteredCommitIndex === null) {