diff --git a/public/app/plugins/panel/flamegraph/components/FlameGraphHeader.tsx b/public/app/plugins/panel/flamegraph/components/FlameGraphHeader.tsx
index 8b062c10bef..46d7803a794 100644
--- a/public/app/plugins/panel/flamegraph/components/FlameGraphHeader.tsx
+++ b/public/app/plugins/panel/flamegraph/components/FlameGraphHeader.tsx
@@ -1,5 +1,7 @@
import { css } from '@emotion/css';
-import React from 'react';
+import React, { useEffect, useState } from 'react';
+import useDebounce from 'react-use/lib/useDebounce';
+import usePrevious from 'react-use/lib/usePrevious';
import { GrafanaTheme2, CoreApp } from '@grafana/data';
import { Button, Input, RadioButtonGroup, useStyles2 } from '@grafana/ui';
@@ -53,17 +55,21 @@ const FlameGraphHeader = ({
setSelectedBarIndex(0);
setRangeMin(0);
setRangeMax(1);
+ // We could set only one and wait them to sync but there is no need to debounce this.
setSearch('');
+ setLocalSearch('');
};
+ const [localSearch, setLocalSearch] = useSearchInput(search, setSearch);
+
return (
{
- setSearch(v.currentTarget.value);
+ setLocalSearch(v.currentTarget.value);
}}
placeholder={'Search..'}
width={44}
@@ -87,6 +93,33 @@ const FlameGraphHeader = ({
);
};
+function useSearchInput(
+ search: string,
+ setSearch: (search: string) => void
+): [string | undefined, (search: string) => void] {
+ const [localSearchState, setLocalSearchState] = useState(search);
+ const prevSearch = usePrevious(search);
+
+ // Debouncing cause changing parent search triggers rerender on both the flamegraph and table
+ useDebounce(
+ () => {
+ setSearch(localSearchState);
+ },
+ 250,
+ [localSearchState]
+ );
+
+ // Make sure we still handle updates from parent (from clicking on a table item for example). We check if the parent
+ // search value changed to something that isn't our local value.
+ useEffect(() => {
+ if (prevSearch !== search && search !== localSearchState) {
+ setLocalSearchState(search);
+ }
+ }, [search, prevSearch, localSearchState]);
+
+ return [localSearchState, setLocalSearchState];
+}
+
const getStyles = (theme: GrafanaTheme2, app: CoreApp) => ({
header: css`
display: flow-root;