Select: Performance improvements when opening menu and when hovering over options (#69230)
This commit is contained in:
@@ -21,7 +21,7 @@ import { SingleValue } from './SingleValue';
|
||||
import { ValueContainer } from './ValueContainer';
|
||||
import { getSelectStyles } from './getSelectStyles';
|
||||
import { useCustomSelectStyles } from './resetSelectStyles';
|
||||
import { ActionMeta, SelectBaseProps } from './types';
|
||||
import { ActionMeta, InputActionMeta, SelectBaseProps } from './types';
|
||||
import { cleanValue, findSelectedValue, omitDescriptions } from './utils';
|
||||
|
||||
interface ExtraValuesIndicatorProps {
|
||||
@@ -155,6 +155,7 @@ export function SelectBase<T>({
|
||||
const reactSelectRef = useRef<{ controlRef: HTMLElement }>(null);
|
||||
const [closeToBottom, setCloseToBottom] = useState<boolean>(false);
|
||||
const selectStyles = useCustomSelectStyles(theme, width);
|
||||
const [hasInputValue, setHasInputValue] = useState<boolean>(!!inputValue);
|
||||
|
||||
// Infer the menu position for asynchronously loaded options. menuPlacement="auto" doesn't work when the menu is
|
||||
// automatically opened when the component is created (it happens in SegmentSelect by setting menuIsOpen={true}).
|
||||
@@ -224,7 +225,9 @@ export function SelectBase<T>({
|
||||
defaultValue,
|
||||
// Also passing disabled, as this is the new Select API, and I want to use this prop instead of react-select's one
|
||||
disabled,
|
||||
filterOption,
|
||||
// react-select always tries to filter the options even at first menu open, which is a problem for performance
|
||||
// in large lists. So we set it to not try to filter the options if there is no input value.
|
||||
filterOption: hasInputValue ? filterOption : null,
|
||||
getOptionLabel,
|
||||
getOptionValue,
|
||||
hideSelectedOptions,
|
||||
@@ -250,7 +253,10 @@ export function SelectBase<T>({
|
||||
menuShouldScrollIntoView: false,
|
||||
onBlur,
|
||||
onChange: onChangeWithEmpty,
|
||||
onInputChange,
|
||||
onInputChange: (val: string, actionMeta: InputActionMeta) => {
|
||||
setHasInputValue(!!val);
|
||||
onInputChange?.(val, actionMeta);
|
||||
},
|
||||
onKeyDown,
|
||||
onMenuClose: onCloseMenu,
|
||||
onMenuOpen: onOpenMenu,
|
||||
|
||||
@@ -99,6 +99,10 @@ export const SelectMenuOptions = ({
|
||||
const theme = useTheme2();
|
||||
const styles = getSelectStyles(theme);
|
||||
const icon = data.icon ? toIconName(data.icon) : undefined;
|
||||
// We are removing onMouseMove and onMouseOver from innerProps because they cause the whole
|
||||
// list to re-render everytime the user hovers over an option. This is a performance issue.
|
||||
// See https://github.com/JedWatson/react-select/issues/3128#issuecomment-451936743
|
||||
const { onMouseMove, onMouseOver, ...rest } = innerProps;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -109,7 +113,7 @@ export const SelectMenuOptions = ({
|
||||
isSelected && styles.optionSelected,
|
||||
data.isDisabled && styles.optionDisabled
|
||||
)}
|
||||
{...innerProps}
|
||||
{...rest}
|
||||
aria-label="Select option"
|
||||
title={data.title}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user