反应选择异步获取

时间:2019-05-21 12:07:30

标签: javascript reactjs react-select

我正在使用react和react-select并尝试从api获取选项。一切都对我有效,但我想显示在从api读取数据时将文本加载到react-select中。

这是我的反应选择组件:

<Select
    onChange={this.getSelectedOption}
    onFocus={this.getData}
    options={options}
    value={selectedOption}
    styles={customStyles}
    placeholder="Select...."
/>

在onFocus中,我通过redux动作进行api调用,并设置来自redux reducer的响应状态。

  getAvailableDisplays() {
    this.props.getData(); /// redux action dispatch
    if (this.props.data.items) {
   this.setState({ this.state.options: this.props.data.items }); }
  }

通过这种方式,一切正常,但是在请求完成时,文本没有选项。

我在这里看到了https://react-select.com/async,但是我不明白在哪里进行api调用。

或者我该如何在api调用完成并填充状态后在select中编写加载内容

1 个答案:

答案 0 :(得分:1)

此处有一些选项可用于从HTTP请求异步加载选项。

仅需注意:如果需要在Redux存储中使用选项,则可以使用Redux mapStateToProps在组件中获取选项,而无需将其设置为组件状态。如果您在商店中不需要它们,则不需要使用Redux操作和reducer,因为您可以直接从组件中执行HTTP / axios请求并将结果设置为组件状态。所提供的示例假设您要使用redux进行操作。

在此沙箱中查看以下组件的工作示例(包装器模拟Redux动作和mapStateToProps):https://codesandbox.io/s/trusting-golick-wx991?file=/src/Selects.js

如果您设置为焦点加载,则使用AsyncSelect将无济于事,因为它仅提供内置选项以在渲染或输入更改时加载。如果要在下拉菜单中显示加载消息,可以通过将选项默认设置为标签中带有加载消息的单个选项并根据加载状态禁用下拉菜单来实现。如果需要,您还可以使用加载状态来在输入框中设置加载消息,而不是在下拉列表中/除了在下拉列表中设置加载消息:

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.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

但是,如果您实际上并没有真正专注于加载选项,则在组件渲染或更改输入(在选择框中键入)时(默认情况下),AsyncSelect将使您非常轻松地加载选项。如果在选项仍在加载时打开,它将在下拉列表中显示“正在加载...”文本:

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..."]} // uncomment this and comment out the line above to load on input change
    />
  );
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

如果您想在输入框中输入加载消息,并且/或者不使用AsyncSelect的下拉菜单,也可以使用加载状态来完成此操作:

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} // uncomment this to disable dropdown until options loaded
  />);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

此外-上面的getAvailableDisplays函数不起作用,因为您正在调用异步getData,然后在异步操作有时间完成之前检查this.props.data.items。