FlameGraph: Debounce search update preventing too frequent rerenders (#68405)

This commit is contained in:
Andrej Ocenas
2023-05-15 14:24:54 +02:00
committed by GitHub
parent e7dc3575d1
commit e6db01dcbe

View File

@ -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 (
<div className={styles.header}>
<div className={styles.leftContainer}>
<div className={styles.inputContainer}>
<Input
value={search || ''}
value={localSearch || ''}
onChange={(v) => {
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;