-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Enhancement] Add menuComponent
option for custom Menu rendering.
#763
Conversation
Doh, accidentally included the [Edit] Aaaaand I forgot to lint... should not PR late at night |
Hey @Craga89, thanks for this! Sounds great, would you mind updating the PR just to include the changes to the |
Rebased with just the |
Rebased into single commit with only the |
className="Select-menu" | ||
style={this.props.menuStyle} | ||
onScroll={this.handleMenuScroll} | ||
onMouseDown={this.handleMouseDownOnMenu}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you have an extra >
?
Added the missing files, removed the syntax error and rebased onto current master :) |
Also added new example that implements react-virtualized to render a large list of 300 items, with virtualized scrolling for perf.
Changes Unknown when pulling cbe2233 on Craga89:master into * on JedWatson:master*. |
@Craga89 nice work 👍 really hoping this gets merged @bvaughn you mentioned in #808 (comment) that you feel that creation of children should be given over to react-virtualized using a factory function or something similar. My understanding is that ReactElements are fairly cheap to create (the expensive part is attaching and rendering them to the DOM) so this PR should get us most of the way. Maybe functionality to provide a factory function for creating options could be a seperate PR as a further optimisation for scenarios when you have very very long list of data and don't want the overhead of creating a whole bunch of ReactElements upfront. |
@Craga89: React elements do seem cheap to create but it still wastes cycles to create them unnecessarily. The main reason I mentioned this is that |
@bvaughn @cloudkite Agreed, it's somewhat of a "bodge" in that sense but really this PR is just to give a general way to replace the We're using the approach mentioned here at work using |
@Craga89, @bvaughn I would advocate trying to get this merged as it is now if @JedWatson is happy with the changes so far. Since its a workable solution for relatively large lists and solves other issues mentioned such as dynamic menu positioning. Then in future another seperate PR could be raised to implement deferred creation of menu options to allow further optimisation, thoughts? |
Incremental changes are good :) I have no objections. (It's up to Jed really.) I am still happy to help with a react-virtualized integration if there's interest. (Happy to do it if it's likely to get merged, would rather not invest a bunch of time if it's unlikely to get merged.) |
Hi again. :) I created a fork of react-select this evening and tried integrating react-virtualized just to see how difficult it would be. In case you're curious...
My fork is obviously a direct integration but it was just intended as a proof of concept. I feel pretty confident about an integration between these 2 libraries now that I've kind of played with it a bit more, but I have one pretty important change I would recommend making. Rather than passing in a pre-rendered renderMenu (options, valueArray, focusedOption) {
if (this.props.renderMenu) {
// This can return a VirtualScroll (or anything else for that matter).
return this.props.renderMenu({
focusedOption,
focusOption: this.focusOption,
options,
selectValue: this.selectValue,
valueArray
});
} else {
// This can return the default, non-virtualized menu.
}
} This would allow you to avoid unnecessarily creating all of the children and tossing away that benefit of react-virtualized. What do you think, @Craga89 and @cloudkite? All that being said, I would be happy to release and maintain an adapter library that sits between react-select and react-virtualized for users who want to enable virtualization by going this route. (I've already reserved an NPM package for this purpose in fact.) |
FWIW I went ahead and tried what I suggested in my own branch.
I think this is the direction to go. I'd be happy to submit a PR (or a patch to this PR) if there's interest. |
FYI I went ahead and submitted a PR with the approach I outlined for easier discussion purposes ~ #859 |
Great job @bvaughn, that looks much more flexible than this approach. Happy to close this if everyone agrees? Though, perhaps having a |
Thank you @Craga89! Fwiw I also released a HOC to make the integration between the 2 libraries easier: https://github.com/bvaughn/react-virtualized-select/ Maybe that helps address your concerns about "simpler use case"? |
Perfect! I'll be using that come Monday! Closing ^_^ |
Currently there's no easy way to override the
Menu
component used internally, in a similar way to theOption
andValue
components.This is handy especially in cases where we want to implement, say, a virtualized scrolling approach when rendering a large amount of items (#738, #554) using
react-virtualized
orreact-list
. It's may also be a possible opportunity to implementreact-tether
to position the menu dynamically based on viewport constraints (#637, #697).I've added new example to the
examples
files that implements the aforementionedreact-virtualized
approach to render a large list of 300 items (also included).