最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React-select Async fetch - Stack Overflow

programmeradmin1浏览0评论

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
Add a ment  | 

1 Answer 1

Reset to default 6

You 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.

发布评论

评论列表(0)

  1. 暂无评论