Closed martinmckenna closed 6 years ago
Hi @martinmckenna! The reason that there isn't any support in the state reducer is because no state change occurs on input focus. If you want to respond to focus of the input then you can apply onFocus
to your input like so:
<input {...getInputProps({onFocus: () => console.log('on focus')})} />
Good luck!
@kentcdodds The problem that I was running into was the fact that (when in use with React), the onFocus
handler was not triggering a render on Downshift's internal render method.
I need a way to change state onFocus and trigger the contents inside Downshift's render method to run
What specifically do you need to have happen?
I want to have the autocomplete items re-appear after something has been typed in, the field has been blurred, then the field was re-focused.
What I've tried is something like this
handleOnFocus = () => {
this.setState({ downShiftIsOpen: true })
}
render() {
return (
<Downshift
onSelect={this.handleSelectSuggestion}
stateReducer={this.downshiftStateReducer}
isOpen={this.state.downShiftIsOpen}
>
{
({
getInputProps,
getItemProps,
isOpen,
inputValue,
highlightedIndex,
}) => {
/*
* The issue here is that none of the below rerenders when the 'downShiftIsOpen'
* state changes, making it impossible to rerender autocomplete suggestions
* when the field is getting re-focused after already being typed into previously
*/
return (
<div>
<TextField
{...getInputProps({
onChange: this.onNodeAddressChange,
placeholder: 'Enter something here...',
value: this.state.fieldValue
onFocus: this.handleOnFocus
})}
/>
{isOpen
this.state.autocompleteItems.map(item => <div>{item.label}</div>)
}
</div>
)
}
}
</Downshift>
)
}
And what I'd like to do is something like this
downshiftStateReducer = (state, changes) => {
switch (changes.type) {
// basically, don't clear the field value when we leave the field
case Downshift.stateChangeTypes.blurInput:
case Downshift.stateChangeTypes.mouseUp:
return {
...changes,
inputValue: state.inputValue || '',
}
case Downshift.stateChangeTypes.focusInput:
return {
...changes,
isOpen: true,
}
default:
return changes;
}
}
render() {
return (
<Downshift
onSelect={this.handleSelectSuggestion}
stateReducer={this.downshiftStateReducer}
>
{
({
getInputProps,
getItemProps,
isOpen,
inputValue,
highlightedIndex,
}) => {
return (
<div>
<TextField
{...getInputProps({
onChange: this.onNodeAddressChange,
placeholder: 'Enter something here...',
value: this.state.fieldValue
})}
/>
{isOpen
this.state.autocompleteItems.map(item => <div>{item.label}</div>)
}
</div>
)
}
}
</Downshift>
)
}
Could you simply use: getInputProps({onFocus: openMenu})
? The openMenu
helper is documented in the README (sorry, short on time otherwise I'd make an example for you).
@kentcdodds ah! yep that works like a charm. Thanks!
Definitely would help to have examples of using the action helpers in the README if you're taking requests for enhancements
@kentcdodds you make this lib fun to use, thanks!
Thanks 😊
Could you simply use:
getInputProps({onFocus: openMenu})
? TheopenMenu
helper is documented in the README (sorry, short on time otherwise I'd make an example for you).
@kentcdodds, @silviuaavram Thanks for the great library!!! Regarding your solution, I was fighting with it for a while. The issue with it is that on input focus, the onFocus
will trigger as expected and the openMenu
will do the job. The issue comes after clicking an option since the onFocus
will fire one more time, it will call openMenu
one more time, and onInputValueChange
will not fire. Not sure if you are firing that onFocus 2 times on purpose, (which may be related to accessibility) or we need to open a bug for it.
Related to this issue, this did the job for me, (opening only if !isOpen):
onFocus: e => {
if (!e.target.value) {
if (!isOpen) {
openMenu();
}
} else {
e.target.select();
}
},
@kentcdodds : I have the problem is like as @constantinpojoga . I can re-create it on the example: https://codesandbox.io/s/github/kentcdodds/downshift-examples?file=/src/hooks/useCombobox/algolia-instantsearch/index.js
You can check the modified source code is forked:
https://codesandbox.io/s/gifted-morning-h9gbf
@meotimdihia @constantinpojoga @silviuaavram I'm experiencing the same problem. Is the solution from @constantinpojoga the only option? Thx in advance!
Problem description: When using the
downshiftStateReducer
, I'd like to be able to add a switch case for input focus