React-Select Async loadOptions is not loading options properly
See original GitHub issueReact Async Select loadoption sometimes fail to loads the option. This is a very strange phenomenon after couple of set of queries react loadoptions don’t load any value but i can see from log that results properly came from backend query. My codebase is totally up to date with react-select new release and using
“react-select”: “^2.1.1”
Here is my front end code for react-async select component. I do use debounce in my getOptions function to reduce number of backend search query. This should not cause any problem i guess. I would like to add another point that i observe in this case, loadoptions serach indicator ( … ) also not appear in this phenomenon.
class SearchableSelect extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: '',
searchApiUrl: props.searchApiUrl,
limit: props.limit,
selectedOption: this.props.defaultValue
};
this.getOptions = _.debounce(this.getOptions.bind(this), 500);
//this.getOptions = this.getOptions.bind(this);
this.handleChange = this.handleChange.bind(this);
this.noOptionsMessage = this.noOptionsMessage.bind(this);
this.handleInputChange = this.handleInputChange.bind(this);
}
handleChange(selectedOption) {
this.setState({
selectedOption: selectedOption
});
if (this.props.actionOnSelectedOption) {
// this is for update action on selectedOption
this.props.actionOnSelectedOption(selectedOption.value);
}
}
handleInputChange(inputValue) {
this.setState({ inputValue });
return inputValue;
}
async getOptions(inputValue, callback) {
console.log('in getOptions'); // never print
if (!inputValue) {
return callback([]);
}
const response = await fetch(
`${this.state.searchApiUrl}?search=${inputValue}&limit=${
this.state.limit
}`
);
const json = await response.json();
console.log('results', json.results); // never print
return callback(json.results);
}
noOptionsMessage(props) {
if (this.state.inputValue === '') {
return (
<Typography {...props.innerProps} align="center" variant="title">
{i18n.get('app.commons.label.search')}
</Typography>
);
}
return (
<Typography {...props.innerProps} align="center" variant="title">
{i18n.get('app.commons.errors.emptySearchResult')}
</Typography>
);
}
getOptionValue = option => {
return option.value || option.id;
};
getOptionLabel = option => {
return option.label || option.name;
};
render() {
const { defaultOptions, placeholder } = this.props;
return (
<AsyncSelect
cacheOptions
value={this.state.selectedOption}
noOptionsMessage={this.noOptionsMessage}
getOptionValue={this.getOptionValue}
getOptionLabel={this.getOptionLabel}
defaultOptions={defaultOptions}
loadOptions={this.getOptions}
placeholder={placeholder}
onChange={this.handleChange}
/>
);
}
}
Issue Analytics
- State:
- Created 5 years ago
- Comments:12 (3 by maintainers)
Top Results From Across the Web
React-Select Async loadOptions is not loading options properly
Here is my front end code for react-async select component. I do use debounce in my getOptions function to reduce number of backend...
Read more >React-Select Async loadOptions is not loading options ...
I found out that people intend to look for this problem. So i am posting my update portion of code that fix the...
Read more >Async - React Select
Use the Async component to load options from a remote source as the user types. import Async, { useAsync } from 'react-select/async'; ...
Read more >React-Select loadOptions conditionally - CodeSandbox
Activating extension 'vscode.typescript-language-features' failed: Could not find bundled tsserver.js.
Read more >Load options on the first open of the Async drop down menu
Reactjs – React-Select Async loadOptions is not loading options properly ... I found out that people intend to look for this problem. So...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The issue is that Lodash’s debounce function is not suitable for this purpose, since subsequent calls to Lodash’s debounced function returns the value of underlying function’s previous value, and not a promise which will resolve to the underlying function’s next invocation value.
This means (with
{leading: true}
not passed to debounce, as in @shakilaust’s code), the first typings into the input within the wait period all returnundefined
(since there was no previous value from the underlying function). This leavesreact-select
in an infinite loading state. After the wait period, any new typing into the input within the wait period again all return the underlying function’s previous value (as lodash’s decounce is spec’ed to do), but in this case that value is now the promise from when the underlying function was called with the previous typing input. Thus, react-select is always one wait period value behind.See an example of this here: https://codesandbox.io/s/oxovwo4ojy
For a full explanation see https://github.com/JedWatson/react-select/issues/3075#issuecomment-450194917
For those finding this issue later, the problem was in how async/await was used for the
getOptions
method. Async/await returns a Promise, while in the code above he was trying to utilize thecallback
version ofloadOptions
, mixing implementations. This is easily fixed by making minor adjustments to the code.