fix: 12861 trim unnecessary re-render in select widget in server side rendering (#12865)

* add debounce to search and remove state var

* increase debounce time
This commit is contained in:
Preet Sidhu 2022-04-12 12:31:51 -04:00 committed by GitHub
parent 4819907a34
commit 19d0db30b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,7 +6,7 @@ import {
IItemListRendererProps, IItemListRendererProps,
IItemRendererProps, IItemRendererProps,
} from "@blueprintjs/select"; } from "@blueprintjs/select";
import { debounce, findIndex, isEmpty, isNil, isNumber } from "lodash"; import { debounce, findIndex, isEmpty, isEqual, isNil, isNumber } from "lodash";
import "../../../../node_modules/@blueprintjs/select/lib/css/blueprint-select.css"; import "../../../../node_modules/@blueprintjs/select/lib/css/blueprint-select.css";
import { FixedSizeList } from "react-window"; import { FixedSizeList } from "react-window";
import { TextSize } from "constants/WidgetConstants"; import { TextSize } from "constants/WidgetConstants";
@ -39,7 +39,6 @@ const MAX_RENDER_MENU_ITEMS_HEIGHT = 300;
interface SelectComponentState { interface SelectComponentState {
activeItemIndex: number | undefined; activeItemIndex: number | undefined;
query?: string;
isOpen?: boolean; isOpen?: boolean;
} }
@ -54,14 +53,12 @@ class SelectComponent extends React.Component<
state = { state = {
// used to show focused item for keyboard up down key interection // used to show focused item for keyboard up down key interection
activeItemIndex: -1, activeItemIndex: -1,
query: "",
isOpen: false, isOpen: false,
}; };
componentDidMount = () => { componentDidMount = () => {
// set default selectedIndex as focused index // set default selectedIndex as focused index
this.setState({ activeItemIndex: this.props.selectedIndex }); this.setState({ activeItemIndex: this.props.selectedIndex });
this.setState({ query: this.props.filterText });
}; };
componentDidUpdate = (prevProps: SelectComponentProps) => { componentDidUpdate = (prevProps: SelectComponentProps) => {
@ -113,15 +110,10 @@ class SelectComponent extends React.Component<
}); });
return optionIndex === this.props.selectedIndex; return optionIndex === this.props.selectedIndex;
}; };
onQueryChange = (filterValue: string) => { onQueryChange = debounce((filterValue: string) => {
this.setState({ query: filterValue }); if (isEqual(filterValue, this.props.filterText)) return;
this.props.onFilterChange(filterValue); this.props.onFilterChange(filterValue);
this.listRef?.current?.scrollTo(0); this.listRef?.current?.scrollTo(0);
if (!this.props.serverSideFiltering) return;
return this.serverSideSearch(filterValue);
};
serverSideSearch = debounce((filterValue: string) => {
this.props.onFilterChange(filterValue);
}, DEBOUNCE_TIMEOUT); }, DEBOUNCE_TIMEOUT);
renderSingleSelectItem = ( renderSingleSelectItem = (
@ -195,7 +187,7 @@ class SelectComponent extends React.Component<
// Don't scroll if the list is filtered. // Don't scroll if the list is filtered.
const optionsCount = this.props.options.length; const optionsCount = this.props.options.length;
const scrollOffset: number = const scrollOffset: number =
!this.state.query && !this.props.filterText &&
isNumber(activeItemIndex) && isNumber(activeItemIndex) &&
optionsCount * ITEM_SIZE > MAX_RENDER_MENU_ITEMS_HEIGHT optionsCount * ITEM_SIZE > MAX_RENDER_MENU_ITEMS_HEIGHT
? activeItemIndex * ITEM_SIZE ? activeItemIndex * ITEM_SIZE
@ -341,7 +333,7 @@ class SelectComponent extends React.Component<
}, },
popoverClassName: `select-popover-wrapper select-popover-width-${this.props.widgetId}`, popoverClassName: `select-popover-wrapper select-popover-width-${this.props.widgetId}`,
}} }}
query={this.state.query} query={this.props.filterText}
scrollToActiveItem scrollToActiveItem
value={this.props.value as string} value={this.props.value as string}
> >