JedWatson / react-select

The Select Component for React.js
https://react-select.com/
MIT License
27.62k stars 4.12k forks source link

React-select is slow when you have more than 1000 items #3128

Closed VladimirMilenko closed 2 years ago

VladimirMilenko commented 6 years ago

Low performance on large sets of options

React-select slows down when you have a huge array of data. Mouse

screenshot 2018-10-19 at 15 29 43 screenshot 2018-10-19 at 15 51 21

FPS drops so low on mouseover, that i can barely use it. In my real case, where i have 1010 items, which i need to show(and i can't load them as user types) - i cannot do anything at all.

You can find a simple example in codesandbox.

https://codesandbox.io/s/q8l6xnvz7w

[Violation] 'mouseover' handler took 346ms
[Violation] 'mouseover' handler took 184ms
[Violation] 'mouseover' handler took 197ms
[Violation] 'mouseover' handler took 172ms
[Violation] 'mouseover' handler took 161ms
[Violation] 'mouseover' handler took 150ms
[Violation] 'mouseover' handler took 167ms
[Violation] 'mouseover' handler took 172ms
[Violation] 'mouseover' handler took 156ms
[Violation] 'mouseover' handler took 166ms

React-select version: 2.1.0

Reflex-Gravity commented 3 years ago

Can anyone give an example to fix this for grouped MenuList? When I use this https://github.com/JedWatson/react-select/issues/3128#issuecomment-576809096 example it overlaps groups on top of each other.

Gazpa commented 3 years ago

Trying this solution: https://codesandbox.io/s/lxv7omv65l with version 2.4.4 of react-select and I cannot reference neither children[index] nor const [value] = getValue()

Is the solution no longer valid in newer versions?

mainfraame commented 3 years ago

Is there any reason why virtualization isn’t built into react-select? I personally cannot think of a reason why it shouldn’t be.

nexeh commented 3 years ago

Can anyone give an example to fix this for grouped MenuList? When I use this #3128 (comment) example it overlaps groups on top of each other.

I have been to this thread many time and I have implemented the solutions listed here with success a number of months ago. Recently I realized that this issue was back and the reason was that we started using the grouped. I am also interested in seeing how to use react-window in this situation.

When using a the grouped feature it changes what you get passed to an array of object, one object for each group that you have which break the example code for using using react-window to resolve the issue. I have tried various attempts to use react-window on each group but nothing has been very fruitful at this point.

Here is a code sand box that implements the above solutions that demonstrates it doesn't work with grouped menu lists. https://codesandbox.io/s/react-select-grouped-large-data-vycpx

Notes:

OptimizedMenuList - FixedSizeList - Child gets called once per group

emmazzw-git commented 3 years ago

Based on the responses above, I came up with this:

import { MenuListComponentProps } from 'react-select/lib/components/Menu'
import { FixedSizeList } from 'react-window'
import { OptionProps } from 'react-select/lib/components/Option'
import { components } from 'react-select'
import React from 'react'

export const optimizeSelect = {
  components: {
    MenuList: OptimizedMenuList,
    Option: OptimizedOption,
  },
}

function OptimizedMenuList(props: MenuListComponentProps<SelectOption>) {
  const { options, children, maxHeight, getValue } = props
  if (!children || !Array.isArray(children)) return null

  const height = 35
  const selectedValues = getValue() as SelectOption[]
  const initialOffset = selectedValues[0] ? options.indexOf(selectedValues[0]) * height : 0

  return (
    <FixedSizeList
      width={''}
      itemSize={height}
      height={maxHeight}
      itemCount={children.length}
      initialScrollOffset={initialOffset}
    >
      {({ index, style }) => (
        <div className="option-wrapper" style={style}>
          {children[index]}
        </div>
      )}
    </FixedSizeList>
  )
}

function OptimizedOption(props: OptionProps<SelectOption>) {
  delete props.innerProps.onMouseMove
  delete props.innerProps.onMouseOver
  return <components.Option {...props}>{props.children}</components.Option>
}

// SelectOption is specific to this example
// and may not work with other projects
type SelectOption = {
  value: string
  label: string
  [key: string]: string
}

Then, whenever I have to optimize a <Select /> I pass a couple of extra props, ie.:

<Select
  {...theOtherProps}
  filterOption={createFilter({ ignoreAccents: false })}
  components={optimizeSelect.components}
/>

Given the required dependencies are installed, others using typescript should be able to create a file for the optimizeSelect and use it as in the example above.

This solution has improved the performance for common browsers like Chrome, Firefox and Safari significantly. For IE, there still seems to be some lagging for large dataset(9563 records). Have you had the same issue?

michael-robbins commented 3 years ago

I'm also seeing performance degradations with IE11 specifically too (chrome/firefox is ok), haven't found a solution yet for IE11 yet...

lynxtaa commented 3 years ago

I was bashing my head against the wall with this performance issue. Then, after watching user behavior, I've noticed that users don't scroll huge lists -- they're using exclusively search. So we've published a version that shows only a portion of options but searches through all of them:

CodeSandbox

import escapeRegExp from "lodash/escapeRegExp";
import React, { useState, useMemo } from "react";
import ReactDOM from "react-dom";
import Select from "react-select";

import "./styles.css";

const MAX_DISPLAYED_OPTIONS = 500;

const options = [];
for (let i = 0; i < 10000; i = i + 1) {
  options.push({ value: i, label: `Option ${i}` });
}

function App() {
  const [inputValue, setInputValue] = useState("");

  const filteredOptions = useMemo(() => {
    if (!inputValue) {
      return options;
    }

    const matchByStart = [];
    const matchByInclusion = [];

    const regByInclusion = new RegExp(escapeRegExp(inputValue), "i");
    const regByStart = new RegExp(`^${escapeRegExp(inputValue)}`, "i");

    for (const option of options) {
      if (regByInclusion.test(option.label)) {
        if (regByStart.test(option.label)) {
          matchByStart.push(option);
        } else {
          matchByInclusion.push(option);
        }
      }
    }

    return [...matchByStart, ...matchByInclusion];
  }, [inputValue]);

  const slicedOptions = useMemo(
    () => filteredOptions.slice(0, MAX_DISPLAYED_OPTIONS),
    [filteredOptions]
  );

  return (
    <Select
      options={slicedOptions}
      onInputChange={(value) => setInputValue(value)}
      filterOption={() => true} // disable native filter
    />
  );
}

ReactDOM.render(<App />, document.getElementById("root"));

Performance issues are gone and nobody noticed that some options are missing (since all options are searchable by typing). It's not a perfect solution but I hope my experience is helpful for someone

jawwadzafar commented 3 years ago

I was bashing my head against the wall with this performance issue. Then, after watching user behavior, I've noticed that users don't scroll huge lists -- they're using exclusively search. So we've published a version that shows only a portion of options but searches through all of them:

CodeSandbox

import escapeRegExp from "lodash/escapeRegExp";
import React, { useState, useMemo } from "react";
import ReactDOM from "react-dom";
import Select from "react-select";

import "./styles.css";

const MAX_DISPLAYED_OPTIONS = 500;

const options = [];
for (let i = 0; i < 10000; i = i + 1) {
  options.push({ value: i, label: `Option ${i}` });
}

function App() {
  const [inputValue, setInputValue] = useState("");

  const filteredOptions = useMemo(() => {
    if (!inputValue) {
      return options;
    }

    const matchByStart = [];
    const matchByInclusion = [];

    const regByInclusion = new RegExp(escapeRegExp(inputValue), "i");
    const regByStart = new RegExp(`^${escapeRegExp(inputValue)}`, "i");

    for (const option of options) {
      if (regByInclusion.test(option.label)) {
        if (regByStart.test(option.label)) {
          matchByStart.push(option);
        } else {
          matchByInclusion.push(option);
        }
      }
    }

    return [...matchByStart, ...matchByInclusion];
  }, [inputValue]);

  const slicedOptions = useMemo(
    () => filteredOptions.slice(0, MAX_DISPLAYED_OPTIONS),
    [filteredOptions]
  );

  return (
    <Select
      options={slicedOptions}
      onInputChange={(value) => setInputValue(value)}
      filterOption={() => true} // disable native filter
    />
  );
}

ReactDOM.render(<App />, document.getElementById("root"));

Performance issues are gone and nobody noticed that some options are missing (since all options are searchable by typing). It's not a perfect solution but I hope my experience is helpful for someone

Thank you!

badwarlock commented 3 years ago

Hi everyone! I spent a few days solving the dropdown list freezing issue. I tried using the above described methods of creating MenuList using react-window. I also added a custom Option component, removing props onMouseMove and onMouseOver. Seems this fixed my problem.

Example with react-window codesandbox.

Update:

Example with react-virtuoso codesandbox.

MenuList

import React from "react";
import { FixedSizeList as List } from "react-window";

const OPTION_HEIGHT = 40;
const ROWS = 6;

const MenuList = ({
  options,
  children,
  getValue
}) => {
  const [value] = getValue();
  const initialOffset =
    options.indexOf(value) !== -1
      ? Array.isArray(children) &&
        children.length >= ROWS
        ? options.indexOf(value) >= ROWS
          ? options.indexOf(value) *
              OPTION_HEIGHT -
            OPTION_HEIGHT * 5
          : 0
        : 0
      : 0;

  return Array.isArray(children) ? (
    <List
      height={
        children.length >= ROWS
          ? OPTION_HEIGHT * ROWS
          : children.length * OPTION_HEIGHT
      }
      itemCount={children.length}
      itemSize={OPTION_HEIGHT}
      initialScrollOffset={initialOffset}
    >
      {({ style, index }) => {
        return (
          <div style={style}>
            {children[index]}
          </div>
        );
      }}
    </List>
  ) : (
    <div>{children}</div>
  );
};

export default MenuList;

Option

import React from "react";
import cx from "classnames";

const Option = ({
  children,
  isSelected,
  innerProps
}) => (
  <div
    className={cx("react-select__option", {
      "react-select__option_selected": isSelected
    })}
    id={innerProps.id}
    tabIndex={innerProps.tabIndex}
    onClick={innerProps.onClick}
  >
    {children}
  </div>
);

export default Option;

ReactSelect

import React from "react";
import Select from "react-select";

import MenuList from "./MenuList";
import Option from "./Option";

const ReactSelect = ({
  options,
  value,
  onChange,
  placeholder
}) => {
  return (
    <Select
      options={options}
      value={value && [value]}
      onChange={onChange}
      classNamePrefix="react-select"
      placeholder={placeholder}
      components={{
        MenuList,
        Option
      }}
    />
  );
};

export default ReactSelect;
chadlavi-casebook commented 3 years ago

We've tried using the react-window solution suggested above, but that solution requires that you know the rendered height of each option. When options in a select are from user-generated content and the menu may be virtually any width, we have to calculate that on the fly every time.

Anyone know a virtualization lib that can be used that doesn't require you to know the exact height as rendered in the browser of every item in the list?

dtaub commented 3 years ago

@chadlavi-casebook I used react-virtuoso. That works pretty nicely for varying height options.

chadlavi-casebook commented 3 years ago

@dtaub thanks, that suggestion looks great. Bonus that it's already written in typescript as well.

phtmgt commented 3 years ago

Using custom menu list here with react-virtualized. Can't figure out the NoOptionsMessage. Just search for a non-existent entry and see what I mean.

Any idea how this can be solved?

cristianlazog commented 3 years ago

You can use this library

https://github.com/jacobworrel/react-windowed-select

Implements both react-select and react-window. Also, you can use the same properties that are available with react-select (https://react-select.com/props)

aaronmw commented 3 years ago

Every time I move my mouse over an option, this component runs filterOption() as if something could possibly have changed other than focus.

I am genuinely perplexed by this performance issue and the maintainers' apparent apathy toward it. If performance tanks with 100+ items, it doesn't belong anywhere near a production environment... Virtualizing the list of options is like using a jackhammer to mount a poster to a wall — a bit much, to say the least.

I guess we need to find an alternative. Pretty infuriating that I'm noticing this issue long after having implemented this component into our design system.

Follow-up: Writing my own Option component that strips out onMouseOver and onMouseMove props seems to work without breaking keyboard functionality. Maybe I'm missing something, but this thing still behaves the same without those props on my Options, which only further confuses me as to why they're on there in the first place 🤔 Thanks to @shunfan and @kotvasili

ebonow commented 3 years ago

@aaronmw

The simple reality is that there is a lot of work to be done by what is essentially a handful of people who are doing so on their free time. Version 5 is still fairly recent and was a huge undertaking and it also forced the team to pause development to achieve parity between what was present in Flow translated into TypeScript. The last few weeks have been focused resolving issues found following the release.

Our next focus will likely be on addressing Menu behavior issues which I spent my weekend searching through open issues to identify and categorize. https://github.com/JedWatson/react-select/discussions/4864 We also would like to address the issues caused by Emotion with the hopes of creating an unstyled version that removes that dependency.

If you would like to contribute more, please feel free to open a discussion so we can talk about performance ideas in depth and in a holistic way that includes the full context of what's being done and why. There are some performance PR's that have been merged https://github.com/JedWatson/react-select/pull/4388 as well as others we'd like to revisit https://github.com/JedWatson/react-select/pull/4514, but our time is finite and would certainly welcome more collaboration.

phtmgt commented 3 years ago

@aaronmw Come on, it's not that much work to write a 20(ish)-line custom MenuList component:

import { List } from 'react-virtualized';

const MenuList = (props: any) => {
  const {
    width,
  } = props.selectProps;
  const rows = props.children;
  const rowRenderer = ({
    key, index, isScrolling, isVisible, style,
  }: rowRendererProps) => (
    <div key={key} style={style}>{rows[index]}</div>
  );

  return (
    <List
      width={width}
      height={Math.min(45 * (rows.length || 0), 315)}
      rowHeight={45}
      rowCount={rows.length || 0}
      rowRenderer={rowRenderer}
    />
  );
};

This is a wonderful project and we should respect the fact people are doing this for free, so they make our lives easier.

lukwallace commented 2 years ago

Just wanted to build on the existing solutions -- this was the one I ended up on. Initial implementation was built off of the solution provided by @badwarlock https://github.com/JedWatson/react-select/issues/3128#issuecomment-847149453

I wanted to have something more keyboard navigable, but it turns out I needed to make it into a controlled component in order to get that to happen.

import React, { useState, useEffect, useRef } from "react";
import Select, { components, createFilter } from 'react-select';
import { Virtuoso } from 'react-virtuoso';

const InnerItem = React.memo(({ children }) => {
  return <>{children}</>;
});

const NUMBER_ITEMS_VISIBLE = 6;
const ITEM_HEIGHT = 60;

const getListHeight = (length) => {
  return length < NUMBER_ITEMS_VISIBLE ?
    length * ITEM_HEIGHT :
    NUMBER_ITEMS_VISIBLE * ITEM_HEIGHT;
};

const CustomMenuList = ({ options, children, getValue, hasValue, focusedOption, ...rest }) => {
    const virtuosoRef = useRef(null);
    const [initialFocus, setInitialFocus] = useState(false);
    const [option] = getValue();

    useEffect(() => {
        let wasSetTrue = false;
        if (virtuosoRef?.current) {
            let selectedOptionIndex = 0;
            // scroll to the selected option
            if (option && !initialFocus) {
                selectedOptionIndex = options.findIndex((item) => item.value === option.value);
                wasSetTrue = true;
            //scroll to the focused option
            } else if (initialFocus && focusedOption) {
                selectedOptionIndex = options.findIndex((item) => item.value === focusedOption.value);
            }
            virtuosoRef.current.scrollToIndex({
                index: selectedOptionIndex,
                align: "center",
                behavior: "auto",
            });
        }
        return () => {
            // Component update to track that we can now scroll to whatever receives focus as opposed to the currently selected option
            if (wasSetTrue) setInitialFocus(true);
        }
    }, [children, virtuosoRef, options, option, getValue, focusedOption, initialFocus]);

    return Array.isArray(children) ? (
        <Virtuoso
            ref={virtuosoRef}
            overscan={{ main: 12, reverse: 12 }}
            style={{ height: `${getListHeight(children.length)}px` }}
            totalCount={children.length}
            itemContent={(index) => <InnerItem children={children[index]} />}
        />
    ) : (
        <div>{children}</div>
    );
};

const CustomOption = ({ children, ...props }) => {
    // Remove the niceties for mouseover and mousemove to optimize for large lists
    // eslint-disable-next-line no-unused-vars
    const { onMouseMove, onMouseOver, ...rest } = props.innerProps;
    const newProps = { ...props, innerProps: rest };
    return (
        <components.Option
            {...newProps}
            className="custom-option"
        >
            {children}
        </components.Option>
    );
};

/**
 * BigSelect
 */
const BigSelect = React.memo((props) => {
    const ref = useRef(null);
    const { value, onChange, ...rest } = props;
    return (
        <Select
            ref={ref}
            {...rest}
            classNamePrefix="big-select"
            components={{
                Option: CustomOption,
                MenuList: CustomMenuList,
            }}
            captureMenuScroll={false}
            filterOption={createFilter({ ignoreAccents: false })}
            value={value}
            onChange={(...args) => {
                onChange(...args);
                if (ref.current) ref.current.setState({ focusedOption: args[0] });
            }}
        />
    );
});

export default BigSelect;

CSS:

.custom-option.big-select__option {
    transition: background 60ms;
    min-height: 60px;
    display: flex;
    align-items: center;
}
.custom-option:hover {
    transition-delay: 60ms;
    background: #e2e6eb;
}
.custom-option.big-select__option--is-focused {
    background: #e2e6eb;
}
.custom-option.big-select__option--is-selected {
    background: #26c2ff;
}
ukhanzada-nisum-com commented 2 years ago

If it's the typing lag that you're bumping on (I was) then it's actually the filterOption={createFilter({ignoreAccents: false})} suggestion by @M1K3Yio that's the gem.

Using this massively reduces the lag when you're typing into the select. I've got a sandbox here that illustrates: https://codesandbox.io/s/zn70lqp31m?fontsize=14

And I've blogged it too

If you guys are using pretty old version like in my case 1.2.0 directly pass ignoreAccents={false} to Select component.

rcketscientist commented 2 years ago

@ebonow

We also would like to address the issues caused by Emotion with the hopes of creating an unstyled version that removes that dependency.

What issues specifically, is this a render delay? I believe we're seeing an issue in a large form where potentially hundreds of selects can create a poor UX due to render delay. If this is related, is there an existing issue? I may want to contribute if I can navigate the emotion spaghetti and ripples it'll cause.

wallzry commented 2 years ago

Hi everyone! I spent a few days solving the dropdown list freezing issue. I tried using the above described methods of creating MenuList using react-window. I also added a custom Option component, removing props onMouseMove and onMouseOver. Seems this fixed my problem.

Example with react-window codesandbox.

Update:

Example with react-virtuoso codesandbox.

MenuList

import React from "react";
import { FixedSizeList as List } from "react-window";

const OPTION_HEIGHT = 40;
const ROWS = 6;

const MenuList = ({
  options,
  children,
  getValue
}) => {
  const [value] = getValue();
  const initialOffset =
    options.indexOf(value) !== -1
      ? Array.isArray(children) &&
        children.length >= ROWS
        ? options.indexOf(value) >= ROWS
          ? options.indexOf(value) *
              OPTION_HEIGHT -
            OPTION_HEIGHT * 5
          : 0
        : 0
      : 0;

  return Array.isArray(children) ? (
    <List
      height={
        children.length >= ROWS
          ? OPTION_HEIGHT * ROWS
          : children.length * OPTION_HEIGHT
      }
      itemCount={children.length}
      itemSize={OPTION_HEIGHT}
      initialScrollOffset={initialOffset}
    >
      {({ style, index }) => {
        return (
          <div style={style}>
            {children[index]}
          </div>
        );
      }}
    </List>
  ) : (
    <div>{children}</div>
  );
};

export default MenuList;

Option

import React from "react";
import cx from "classnames";

const Option = ({
  children,
  isSelected,
  innerProps
}) => (
  <div
    className={cx("react-select__option", {
      "react-select__option_selected": isSelected
    })}
    id={innerProps.id}
    tabIndex={innerProps.tabIndex}
    onClick={innerProps.onClick}
  >
    {children}
  </div>
);

export default Option;

ReactSelect

import React from "react";
import Select from "react-select";

import MenuList from "./MenuList";
import Option from "./Option";

const ReactSelect = ({
  options,
  value,
  onChange,
  placeholder
}) => {
  return (
    <Select
      options={options}
      value={value && [value]}
      onChange={onChange}
      classNamePrefix="react-select"
      placeholder={placeholder}
      components={{
        MenuList,
        Option
      }}
    />
  );
};

export default ReactSelect;

Works perfectly! Btw styling can be done inside the MenuList component like this:

<div style={{ ...style, height: 80, padding: 10, cursor: "pointer" }}>
{children[index]}
</div>

or like this: (tailwind itc)

<div style={style} className="hover:bg-main p-2 cursor-pointer">
{children[index]}
</div>
lukebennett88 commented 2 years ago

Hi @VladimirMilenko,

In an effort to sustain the react-select project going forward, we're cleaning up and closing old issues and pull requests.

We understand this might be inconvenient but in the best interest of supporting the broader community we have to direct our efforts towards the current major version.

If you aren't using the latest version of react-select please consider upgrading to see if it resolves any issues you're having.

However, if you feel this issue is still relevant and you'd like us to review it - please leave a comment and we'll do our best to get back to you!

loiclecolier commented 1 year ago

I have 50,000 items in my Select from react-select. I tried many things to improve performance: set ignoreAccents to false, disable onMouseMove and onMouseOver events and virtualization. But it's still slow.

Taking up @lynxtaa 's idea, I found the react-select-async-paginate library which allows you to "paginate" the items, and to retrieve the ones you want with the search.

The library : https://www.npmjs.com/package/react-select-async-paginate Example: https://codesandbox.io/s/10r1k12vk7?file=/src/App.jsx:673-688

aprilmintacpineda commented 1 year ago

I have just 1000 items, it's already very laggish.

keepforever commented 1 year ago

i love how this thread is still going after all this time.

just ask GPTChat to write your implementation.

Or paste (a simplified version) of your implementation into GPTChat and ask it to correct. Tell it what's wrong. Show it where it hurts. It will help you.

🤖🤖🤖

aprilmintacpineda commented 1 year ago

Yeah, well, I was brought here in search of a built-in option for virtualization, honestly, I believe that a library that handles select dropdowns should have that option built-in. The fact that this is still going since 2018 should already tell everyone that there's real demand for it.

But since react-select seems to not be bothered by it, I just followed the react-window approach.

rcketscientist commented 1 year ago

Yeah, well, I was brought here in search of a built-in option for virtualization, honestly, I believe that a library that handles select dropdowns should have that option built-in. The fact that this is still going since 2018 should already tell everyone that there's real demand for it.

But since react-select seems to not be bothered by it, I just followed the react-window approach.

The entitlement of kids these days.

aprilmintacpineda commented 1 year ago

Yeah, well, I was brought here in search of a built-in option for virtualization, honestly, I believe that a library that handles select dropdowns should have that option built-in. The fact that this is still going since 2018 should already tell everyone that there's real demand for it. But since react-select seems to not be bothered by it, I just followed the react-window approach.

The entitlement of kids these days.

Such a judgemental state of mind.

SeanRoberts commented 1 year ago

Yeah, well, I was brought here in search of a built-in option for virtualization, honestly, I believe that a library that handles select dropdowns should have that option built-in. The fact that this is still going since 2018 should already tell everyone that there's real demand for it.

I'm pretty sure this project is accepting PRs

aprilmintacpineda commented 1 year ago

There's a PR addressing the performance on large lists. The solution followed the memoization of buildCategorizedOptions rather than virtualization.

Methuselah96 commented 1 year ago

If you're referring to https://github.com/JedWatson/react-select/pull/5450, virtualization and disabling stripping diacritics have a much bigger impact on performance for large lists. That PR just makes it even faster assuming you're already doing those performance improvements.

gydotitulaer commented 1 year ago

Hi @VladimirMilenko,

In an effort to sustain the react-select project going forward, we're cleaning up and closing old issues and pull requests.

We understand this might be inconvenient but in the best interest of supporting the broader community we have to direct our efforts towards the current major version.

If you aren't using the latest version of react-select please consider upgrading to see if it resolves any issues you're having.

However, if you feel this issue is still relevant and you'd like us to review it - please leave a comment and we'll do our best to get back to you!

We’ve updated the tool from v2.x to v5.x last week and the performance issues are still there. I wanted to let you know.

i’ve seen couple of workarounds and tips how to improve the performance, we are going to look into them next week and will let you guys know our findings.

Edit: We did not check other options for performance gains apologies

vikrant-gembrill commented 1 year ago

ignoreAccents

if i am using the filterOption for custom logic, then how can i set ignoreAccents: i am using filterOption like this

filterOption={(option, inputValue) => {
                    if (option?.data?.text) {
                      return (
                        (
                          option.data.text
                            .toString()
                            .toLowerCase()
                            .match(inputValue.toString().toLowerCase()) || []
                        ).length > 0
                      );
                    }
                  }}
timjahn93 commented 1 year ago

Hi @vikrant-gembrill,

Same problem. Did you find a solution?

vikrant-gembrill commented 1 year ago

@timjahn93 did not find a solution to filter option issue but, what i found was react select was very slow when the developer tools was open in chrome. Also, if there is huge data, better use virtualization with react window. Also check your extensions.

timjahn93 commented 1 year ago

@vikrant-gembrill Okay, I am using virtualization already, but using my own filter option, react select is too slow with high data and the page collapses. With createFilter and ignoreAccents it is way more performant.

Tibesti commented 7 months ago

Just as a reference for anyone else who might encounter this problem, the solution using filterOption works like magic: filterOption={createFilter({ ignoreAccents: false })}