Using react-select v2, I want to show and focus on the Select element when the user hits a certain key. Following are some things I've tried or paths I've gone down.
When I set a ref to the Select element and try to call .focus
on it, it says no focus function is found. Perhaps I should somehow get a child element of it and then call focus on that?
There doesn't seem to be any prop I can pass that will trigger a focus function. There is an openOnFocus
but not a focusOnOpen
. The only thing I can think of would be to enable autoFocus and then somehow trigger a remount but there doesn't seem to be a simple way to do this and it feels hacky. Alternatively, I could enable just create the Select component each time the key is pressed instead of showing it, then unmount it instead of hiding it.
How can I properly get the react-select element to gain focus when I want it to?
I'm using a wrapper component around my component. Here's the render method for my wrapper:
render() {
return (
<Select
options={this.props.options}
value={this.state.value}
ref={this.selectRef}
/>
);
}
And here's where I'm calling that wrapper:
<Wrapper
options={this.props.labelOptions}
ref={this.wrapperRef}
/>
I then try calling focus using either this.dropdownNode.focus()
or this.dropdownNode.current.focus()
and both say no focus method is found.
Because you're wrapping the Select
component, you can't call Select's .focus()
function from the ref you're giving to the wrapper. Since ref
is a special kind of prop, the ref for that wrapper is only referring to Wrapper
itself, not the component it wraps (Select).
To access the actual Select
component's ref, you have to pass a ref down to it as a prop with a different, non-magic name, like innerRef
(react-select code actually gives a good example of this as it's accessing the actual input element and focusing on that).
Here's the change that fixed it. Here is the wrapper component where Select is actually used (and it's taking in the ref passed to it):
render() {
return (
<Select
options={this.props.options}
value={this.state.value}
ref={this.props.innerRef}
/>
);
}
And here's the component that's calling that wrapper. In the constructor I'm creating the ref with this.selectRef = React.createRef()
then I pass it in as a prop in this render method:
<Wrapper
options={this.props.labelOptions}
innerRef={this.selectRef}
/>
Then I can call focus on the Select
component itself by running this.selectRef.current.focus()
anywhere I want to.
Notes: Thanks to BoyWithSilverWings answer. This question pertains to React 16.3. There is also a new React.ForwardRefs
method but this way seems simpler to me.