I'm using react and react-select and trying getting options from the api. Everything work on me but I want to show loading text into react-select while data ing from the api.
Here is my react-select ponent:
<Select
onChange={this.getSelectedOption}
onFocus={this.getData}
options={options}
value={selectedOption}
styles={customStyles}
placeholder="Select...."
/>
and here in onFocus I make api call via redux action and set the state with response which ing from redux reducer.
getAvailableDisplays() {
this.props.getData(); /// redux action dispatch
if (this.props.data.items) {
this.setState({ this.state.options: this.props.data.items }); }
}
With this way everything work but while request finish there is text no options..
I saw here something but I can't understand where make api call.
Or how can I just write loading in select while api call finished and state filled
I'm using react and react-select and trying getting options from the api. Everything work on me but I want to show loading text into react-select while data ing from the api.
Here is my react-select ponent:
<Select
onChange={this.getSelectedOption}
onFocus={this.getData}
options={options}
value={selectedOption}
styles={customStyles}
placeholder="Select...."
/>
and here in onFocus I make api call via redux action and set the state with response which ing from redux reducer.
getAvailableDisplays() {
this.props.getData(); /// redux action dispatch
if (this.props.data.items) {
this.setState({ this.state.options: this.props.data.items }); }
}
With this way everything work but while request finish there is text no options..
I saw here something https://react-select./async but I can't understand where make api call.
Or how can I just write loading in select while api call finished and state filled
Share Improve this question edited May 22, 2019 at 19:13 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked May 21, 2019 at 12:07 user3348410user3348410 2,84311 gold badges56 silver badges91 bronze badges 2- can you share a codesandbox? From what you've given, it is not clear how you are making the api call currently. – Dani Vijay Commented May 21, 2019 at 13:30
- How i can make api call? :) i'm using axios get response of data and set it to ponent state – user3348410 Commented May 21, 2019 at 13:56
1 Answer
Reset to default 6You have a few options here for loading options asynchronously from an HTTP request.
Just a note: if you need your options in the Redux store, you can get your options in your ponent using Redux mapStateToProps, no need to set them in ponent state. If you don't need them in the store, using a Redux action and reducer is unnecessary since you can just execute your HTTP/axios request directly from your ponent and set the result in your ponent state. Examples provided assuming you want to do this using redux.
Check out this sandbox for working examples of the below ponents (wrapper simulating Redux actions and mapStateToProps): https://codesandbox.io/s/trusting-golick-wx991?file=/src/Selects.js
If you are set on loading on focus, using AsyncSelect won't help you since it only provides builtin options to load on render or on input change. If you want to show the loading message in the dropdown, you can do so by setting the options to default to a single option with the loading message in the label and disabling the dropdown depending on loading state. You can also use loading state to set the loading message in the input box, instead of/in addition to in the dropdown, if desired:
const MySelect = props => {
const [loading, setLoading] = useState(false);
const [hasLoaded, setHasLoaded] = useState(false);
const handleFocus = () => {
if (!props.options && !hasLoaded) {
setLoading(true);
setHasLoaded(true);
return props.getData().then(() => setLoading(false));
}
};
return (
<Select
onFocus={handleFocus}
options={props.options || [{ value: 0, label: "Loading..." }]}
placeholder={loading ? "Loading options..." : "Select...."}
isDisabled={loading}
/>
);
};
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
However, if you aren't actually set on loading the options on focus, AsyncSelect will let you very easily load the options either when the ponent renders or when the input is changed (typing in the select box), and by default it will show "Loading..." text in the dropdown if it's open while options are still loading:
const MyAsyncSelect = props => {
return (
<AsyncSelect
loadOptions={props.getAsyncData} // function that executes HTTP request and returns array of options
placeholder={"Select...."}
defaultOptions // load on render
// defaultOptions={[id: 0, label: "Loading..."]} // unment this and ment out the line above to load on input change
/>
);
};
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
If you want the loading message in the input box as well as/instead of the dropdown for AsyncSelect, you can acplish this using loading state as well:
const MyAsyncSelectLoading = props => {
const [loading, setLoading] = useState(false);
const getData = () => {
return props.getAsyncData().then(result => {
setLoading(false);
return result;
});
};
return (<AsyncSelect
loadOptions = {getData}
placeholder = {loading ? "Loading data" : "Select...."}
defaultOptions
// isDisabled={loading} // unment this to disable dropdown until options loaded
/>);
};
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Also - the above getAvailableDisplays function wouldn't work, because you're calling asynchronous getData, then checking this.props.data.items before the asynchronous action has had time to plete.