Using redux and react-select the input text is cleared in the following two scenarios:
I am using react and redux with an immutable state . I am not sure if that could affect but mentioning it just in case. When I click on the option list it does update the state and the textbox correctly.
At the beginning I though it could be related to async calls but I do not think that could affect as I am leaving redux deal with it and in the component I display whatever the properties have. Debugging my issue, I can see that the state is being updated but the input text for some reason does not display what the state has. I am happy to contribute with a PR if needed, I just need some sort of direction on where could the error be happening.
It seems that something apart from my intention is calling the interceptor onInputChange . If I set a log it comes as empty despite the fact that I am always returning the value sent. Moreover, when pressing enter in the list of options it updates the state but does not display the text in the select textbox.
class Selector extends Component {
```
componentWillMount()
{
this.onChange = this.onChange.bind(this);
this.onInputChange = this.onInputChange.bind(this);
this.dispatchSuggestions = this.dispatchSuggestions.bind(this);
}
onChange(selectedOption){
let newValue='';
if(selectedOption !== null){
newValue=selectedOption.name;
}
this.props.actions.updateTextSuccess(newValue.toLowerCase(),
this.props.questionId, this.props.partId)
}
async dispatchSuggestions(newTextValue)
{
//First update the text so the api can take the first characters that we are looking for in the options
let updatingText= await this.props.actions.updateTextSuccess(newTextValue,
this.props.questionId,
this.props.partId);
//dispatch the options
let updatingSuggestions=await this.props.actions.loadSuggestions(
this.props.parts.get('byPartId'),
this.props.questionId,
this.props.partId);
return updatingText;
}
async onInputChange (newTextValue)
{
//when the user types the third character dispatch an action to load the options and return the
//newTextValue
if(newTextValue.length===3 && newTextValue.trim() !=="")
{
return await this.dispatchSuggestions(newTextValue)
}
return newTextValue;
}
render () {
let suggestions=[];
if(this.props.part.get('suggestions').size === undefined){
suggestions=this.props.part.get('suggestions');
}
else {
suggestions=this.props.part.get('suggestions').toJS(); //toJS because my state is immutable
}
return (
options={suggestions}
labelKey='name'
valueKey='name'
value={this.props.part.toJS().text}
onChange={this.onChange}
onInputChange={this.onInputChange}
/>
)
}
}
```
Well, after a couple of hours diving into this issue, I found the reason. We moved from 1.1.0
to 1.2.1
and then everything started to fails, primary on async calls + redux.
If you see this commit has introduced a fix to clear the input after refresh inputValue props.
https://github.com/JedWatson/react-select/commit/936dd6e792d1866128819dace1b77a8b50a7eb2f and especially this commit https://github.com/JedWatson/react-select/commit/ae26bf80d10112b1407e1d34e7fa00caa1fe8699 which force by default to clear the input text after each new props are received because onSelectResetsInput is TRUE by default (https://github.com/JedWatson/react-select/blob/0d0ccd3acc4efdba0b32d711a6c16809a6d779b4/src/Select.js#L1212)
Changes are visible here as well https://github.com/JedWatson/react-select/blame/c9d027387a77b3695fdfbb3d4de25ffcea9505ee/src/Select.js#L144
My solution was force onSelectResetsInput to false, and then all works properly.
import ReactSelect from "react-select";
render() {
return <ReactSelect {...props} onSelectResetsInput={false}/>;
}
Disclaimer: Setting of onSelectResetsInput will avoid clear the text obviously. So I'm not sure whether is intended or a bug
-- Update --
https://codesandbox.io/s/o4y2p39o29
Thanks @juanpicado I really liked your very clear explanation. Your solution definitely does the trick, do you think it would be necessary to create a PR to solve the issue form the root :) I am happy to help (will be off next week but happy to contribute when I am back).
On another topic, I just found out a very weird behaviour. If my dataset is in _lower case_ it works properly but if it is _capitalized_ it doesn't. For example: from the following list if I press enter or click on Commoners it doesn't pupulate the textbox but if I press enter or click on customer it works fine. I am wondering if it is just me doing something weird or anybody is having that weird issue.
options:[ { name: 'customers'},
{ name: 'clients' },
{ name: 'Commoners' },
{ name: 'Custom'} ]
@itReverie you are welcome. For your two questions let's wait the thoughts of the library's author I have no clue at this moment.
if (this.state.inputValue && this.props.value !== nextProps.value && nextProps.onSelectResetsInput) {
this.setState({ inputValue: this.handleInputValueChange('') });
}
Using Redux this.props.value !== nextProps.value
value we do not mutate and update the store, thus, in the app side (specially if the options comes from some endpoint) and will never will be ===
(eg: empty results ([]!==[]) // this is true
, this.state.inputValue
is true obviously and having onSelectResetsInput
true by default.
In the previous video, when I'm waiting for a new set of options, the component clears the input and triggers at the same time onInputChange
reaching my app again.
I'd say this component is not Redux friendly 😞 . I'm trying to figure out how to keep the state in a way those conditions do not resolve true.
That cause the following issue clearing the inputValue
:
As I mentioned before, my workaround is set onSelectResetsInput=false but then the text is not cleared and you have the following behavior (the inputValue remains there until the component loses the focus):
https://github.com/JedWatson/react-select/commit/936dd6e792d1866128819dace1b77a8b50a7eb2f#diff-04191649796841200b33375bdff7c78fR105
I had to make the following changes to get our search working as expected:
<Select.Async
placeholder="Placeholder"
loadOptions={this.state.debouncedFetchOptions}
value={this.state.selection.value}
+ onSelectResetsInput={false}
+ onBlurResetsInput={false}
onChange={this._onChange}
/>
Sorry I am on holidays and haven't had a chance to look at it deeply. @juanpicado in my case the state seems to be updated correctly but the component does not reflect what the state has.
By any chance do you have the same issue as me with the capitalize options.
@kimmobrunfeldt thanks for the tip, are you using redux?
@itReverie Yeah, using Redux.
I think it is working. @juanpicado I am using redux and it does keep the state so the component is working ok with redux (my example repo https://github.com/itReverie/itr-react-redux-normalizr/tree/virtualizedSelectAsync), thanks for your help.
@kimmobrunfeldt thanks also sadly we need those conditionals to false to make it work.
Forcing us to set onSelectResetsInput
to false
changes the UX of the component in a way that I don't want – I wouldn't consider this issue to be closed.
Hi, guys!
Who knows, why placeholder in Select can leave input field and place up on the input field? I use react-select 1.3.0
@ShmidtAlex I have same problem, after select input still contains old is-pseudo-open class and user can do re select.
@ShmidtAlex @vaske I have the same issue, how to remove the the placeholder.
I am using inputRenderer
and if i try to manage the place-holder text with react state
I run into a maximum call stack exceeded error.
Most helpful comment
I had to make the following changes to get our search working as expected: