【问题标题】:React-select Async fetch反应选择异步获取
【发布时间】:2019-10-07 19:52:58
【问题描述】:

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

这是我的 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 中写入加载

【问题讨论】:

  • 你能分享一个密码箱吗?根据您提供的信息,目前尚不清楚您是如何进行 api 调用的。
  • 如何进行 api 调用? :) 我正在使用 axios 获取数据响应并将其设置为组件状态

标签: javascript reactjs react-select


【解决方案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。

【讨论】:

  • 如何获取选中的值?我是这个图书馆的新手,但还没有弄清楚。我需要将所选值写入我的用例中的另一个状态变量。
猜你喜欢
  • 2021-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-03
  • 1970-01-01
  • 2019-02-10
  • 1970-01-01
相关资源
最近更新 更多