Hey - I'm using react-select with a list of 2500 elements. I find the box to be slow, especially when i'm deleting characters. Is there a more efficient way of managing a large list in react-select?
I also have the same problem. I think there should be a way to buffer a long list (similar to the solution used in some grid components, where only the rows that are effectively on the screen are rendered).
Same here. I have an list of around 1200 element, and the select2 component is lagging when scrolling and hovering on select2 items.
I ended up filtering the list via loadOptions={that.getOptions} where getOptions was
getOptions: function(input, callback) {
var that = this;
if (input.length > 0) {
var searchString = input.toLowerCase().trim();
var options = that.state.options.filter(function(d) {
return d.query.match( searchString );
});
} else {
var options = "";
}
return (
callback(null, {
options: options.slice(0, 10)
})
);
},
where each element in options has a well-defined "query" string
This ends up being insanely fast
Check out PR #859 (and the demo linked) which adds react-virtualized support.
Update: If you're able to use react-select 1.0.0 beta, then you might be interested in trying a new HOC, react-virtualized-select. Does windowing/lazy rendering so it should help with the issue you're reporting.
Chiming in after some time.
I _think_ this problem (slow filtering) comes down to how filtering is done within react-select
(aka synchronously, in the UI thread. For large lists, this approach is going to hurt FPS.
I've created some JS search libs (eg js-worker-search
, redux-search
) that manage filtering in web-workers, using data structures optimized for fast look-up, and the response time for filtering drop-down lists using them is _very fast_.
Perhaps that would be interest in trying to integrate one of these libs with react-select
? Perhaps even as an external HOC (similar to react-select-virtualized
) that just exported a filterOptions
function that could be passed as a prop to override the built-in react-select
filter.
If there's interest, I would be happy to take a stab at it. Let me know!
To add a little more context...
I like using high-order components for this sort of functionality because (a) it doesn't bloat or add complexity to the underlying library (react-select
) and (b) it lets users opt-in if they need the functionality. Lots of users just want a simple, styled drop-down menu and vanilla react-select
works fine for that.
I was tentatively thinking of creating another light-weight lib that connects js-worker-search
and react-select
so people wanting to filter large lists of options could use _that_ library as their filterOptions
property. So basically something like this...
import React from 'react'
import VirtualizedSelect from 'react-virtualized-select'
import fastFilterOptions from 'react-select-fast-filter-options'
function MyComponent () {
return (
<VirtualizedSelect
{...props}
filterOptions={fastFilterOptions}
/>
)
}
New high-order component available to hopefully speed things up a lot!
Demo available here with 100,000 options: https://bvaughn.github.io/react-select-fast-filter-options/
Source and installation instructions here: https://github.com/bvaughn/react-select-fast-filter-options
Going to close this issue since react-select-fast-filter-options
provides a lightweight way to improve filtering performance. I briefly considered making it the _default_ filterOptions
implementation within react-select
(and may still at some point) but didn't want to pull in the extra dependency on js-search
for users with small options lists and simpler use-cases.
I've added a new section to the README making mention of this new library. Since I own react-select-fast-filter-options
and js-search
and I'm a collaborator on react-select
as well- it should be easy to keep these libraries in sync going forward.
@bvaughn is there an update to your solution? Your demo seems to be broken.
Your demo seems to be broken.
In what way? Demo works for me.
@bvaughn It seems scrolling through causes an error passed 40 entries. Issue appears to be on official documentation as well #1438
@bvaughn Sorry for the confusion. I was looking at https://bvaughn.github.io/react-select-fast-filter-options/
It seems your demo at http://bvaughn.github.io/react-virtualized-select/ works just fine.
Interesting. Could not repro that error with my local build but I _did_ see it on the site. Rebuild and redeployed. Maybe a transient issue with dependencies. Soon as the cache clears it should be fine.
Is there a solution to increase performance for version ^2.0?
(react-virtualized-select and react-select-fast-filter-options seem to still work with 1.0)
I ended up creating my own component to handle this situation with something like this:
import React, { Component } from 'react'
import Select from 'react-select'
import { filter } from 'lodash/fp'
class LargeSelect extends Component {
constructor(props){
super(props)
this.state = {
inputValue: this.props.inputValue || "",
displayedOpts: this.props.allOpts.slice(0, this.props.maxDisplayed),
}
this.handleInputChange = this.handleInputChange.bind(this)
}
handleInputChange(inputValue) {
const displayedOpts = filter(
({label}) => label.toLowerCase().includes(inputValue.toLowerCase()),
this.props.allOpts,
).slice(0, this.props.maxDisplayed)
this.setState({inputValue, displayedOpts})
}
render(){
return (
<Select
isMulti
options={this.state.displayedOpts}
onInputChange={this.handleInputChange}
onChange={this.props.onChange}
value={
filter(
({value}) => this.props.value.includes(value),
this.props.allOpts,
)
}
/>
)
}
}
LargeSelect.defaultProps = {
onChange: () => {},
maxDisplayed: 20
}
export default LargeSelect
Your demo seems to be broken.
In what way? Demo works for me.
It can not load react-select.css from
https://unpkg.com/[email protected]/dist/react-select.css
@bvaughn Is there a version of react-fast-filter-options for react-select v2? I need the flexibility of v2, such as the menuIsOpen
prop. Thanks!
Don't know. I've never used v2, sorry!
so sad. I assume you've stopped using this library altogether? It just
seemed really hard to customize in the first iteration, so I want to use
v2.
On Tue, Nov 27, 2018 at 10:24 AM Brian Vaughn notifications@github.com
wrote:
Don't know. I've never used v2, sorry!
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/JedWatson/react-select/issues/739#issuecomment-442098499,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AZHNAX0ZWvXjTSRkycxjoEbXw7S-1rohks5uzVk8gaJpZM4HN_JB
.
--
Will Borwegen
I ended up filtering the list via loadOptions={that.getOptions} where getOptions was
getOptions: function(input, callback) { var that = this; if (input.length > 0) { var searchString = input.toLowerCase().trim(); var options = that.state.options.filter(function(d) { return d.query.match( searchString ); }); } else { var options = ""; } return ( callback(null, { options: options.slice(0, 10) }) ); },
where each element in options has a well-defined "query" string
This ends up being insanely fast
mind if i ask you to show me your
select component
Most helpful comment
Is there a solution to increase performance for version ^2.0?
(react-virtualized-select and react-select-fast-filter-options seem to still work with 1.0)