问题
I don't know whyreact-select is clearing what I am typing after the second or third character. Based on my log the state had been updated correctly. I am thinking it could be that the operations happen async but even if that were the case after the update I would expect the text on the select to be updated according to the state. Apart from that when selecting an option from the list and pressing enter it doesn't display the selection on the textbox but it does recognizes the selection as it updates the state.
Any direction to point me to where is my error would be appreciated.
My repo is the following on the branch (virtualizedSelectAsync)
https://github.com/itReverie/itr-react-redux-normalizr/tree/virtualizedSelectAsync
My component is the following:
class Selector extends Component {
componentWillMount()
{
this.onChange = this.onChange.bind(this);
this.onInputChange = this.onInputChange.bind(this);
this.dispatchSuggestions = this.dispatchSuggestions.bind(this);
}
//I update the state just when an option has been selected
onChange(selectedOption){
let newValue='';
if(selectedOption !== null){
newValue=selectedOption.name;
}
this.props.actions.updateTextSuccess(newValue.toLowerCase(),
this.props.questionId,
this.props.partId)
}
dispatchSuggestions(newTextValue)
{
//First I update the state of the text with the values I want to send to the API and provide me suggestions based on that value
return
this.props.actions.updateTextSuccess(newTextValue.toLowerCase(),
this.props.questionId,
this.props.partId)
.then(data => {
//After updating the text then dispatch the action to load
//the suggestions
return this.props.actions.loadSuggestions(
this.props.parts.get('byPartId'),
this.props.questionId,
this.props.partId)
.then(textUpdated=>{return textUpdated;})})
}
onInputChange (newTextValue)
{ //I just want to dispatch the suggestions after the user has typed
// 3 characters so the API has some context and return the
// necessary suggestions
if(newTextValue.length===3 && newTextValue.trim() !=="")
{
return Promise.resolve( 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();
}
return (
<VirtualizedSelect style={{width:'180px'}}
options={suggestions}
labelKey='name'
valueKey='name'
value={this.props.part.toJS().text}
onChange={this.onChange}
onInputChange={this.onInputChange}
/>
)
}
}
Note: I am using Virtualized select but the behaviour is the same with Select.
回答1:
Based on the reported issue on GitHub https://github.com/JedWatson/react-select/issues/2405
It seems something is broken from version 1.1.0 to 1.2.1 because onSelectResetsInput is TRUE by default. The trick would be to add **onSelectResetsInput={false} onBlurResetsInput={false}**
render() {
return <ReactSelect {...props} onSelectResetsInput={false} onBlurResetsInput={false}/>;
}
回答2:
Yep, looks like an async issue with return Promise.resolve( this.dispatchSuggestions(newTextValue))
. You should look into using async/await or you should fire off the action and then return the text.
async onInputChange (newTextValue)
{ //I just want to dispatch the suggestions after the user has typed
// 3 characters so the API has some context and return the
// necessary suggestions
if(newTextValue.length===3 && newTextValue.trim() !=="")
{
return await Promise.resolve( this.dispatchSuggestions(newTextValue))
}
return newTextValue;
}
OR...
onInputChange (newTextValue)
{ //I just want to dispatch the suggestions after the user has typed
// 3 characters so the API has some context and return the
// necessary suggestions
if(newTextValue.length===3 && newTextValue.trim() !=="")
{
Promise.resolve( this.dispatchSuggestions(newTextValue));
}
// Always return the entered text value
return newTextValue;
}
来源:https://stackoverflow.com/questions/49017633/react-select-oninputchange-clears-value-and-does-not-update-the-textbox-with-the