Reactjs - 通过在自动完成组件中的每个输入更改时点击 API 来更新选项 (Material UI)

Reactjs - Update options by hitting API on every input change in Autocomplete component (Material UI)

我是 Reactjs 的初学者。我想创建一个自动完成组件,在每次输入更改时都会点击 API 并相应地更新选项。我正在使用 Material UI 提供的自动完成组件。据我了解,给出的例子here hits an API once and filters it locally. I tried using the InputChange props provided by material component. Also I found this anser - 。但是想不出正确的方法。

import Autocomplete from "@material-ui/lab/Autocomplete";
import TextField from "@material-ui/core/TextField";
import {CircularProgress} from "@material-ui/core";
import debounce from 'lodash/debounce';

const SelectField = ({inputLabel}) => {
    const [ open, setOpen ] = React.useState(false);
    const [ options, setOptions ] = React.useState([]);
    const [ inputValue, setInputValue ] = React.useState("");
    const loading = open && options.length === 0;

    const onInputChange = debounce((event, value) => {
        console.log("OnInputChange",value);
        setInputValue(value);
        (async() => {
            const response = await fetch('https://api.tvmaze.com/search/shows?q='+inputValue);
            console.log("API hit again")
            let movies = await response.json();

            if(movies !== undefined) {
                setOptions(movies);
                console.log(movies)
            }
        })();
    }, 1500);

    return (
        <Autocomplete
            style={{ width:300 }}
            open={open}
            onOpen={() => {
              setOpen(true);
            }}
            onClose={() => {
              setOpen(false);
            }}
            getOptionLabel={(option) => option.show.name}
            onInputChange={onInputChange}
            options={options}
            loading={loading}
            renderInput={(params) => (<TextField
                {...params}
                label={inputLabel}
                variant="outlined"
                InputProps={{
                  ...params.InputProps,
                  endAdornment: (
                      <React.Fragment>
                          {loading ? <CircularProgress color="inherit" size={20} />: null }
                          {params.InputProps.endAdornment}
                      </React.Fragment>
                  ),
                }}
              />
            )}
        />
    );
}

export default SelectField;

我遇到过这个问题,我在用户输入时手动调用了 API。找到沙箱的 link。检查自动完成内呈现的文本字段的 onChange 道具

// *https://www.registers.service.gov.uk/registers/country/use-the-api*
import fetch from "cross-fetch";
import React from "react";
import TextField from "@material-ui/core/TextField";
import Autocomplete from "@material-ui/lab/Autocomplete";
import CircularProgress from "@material-ui/core/CircularProgress";


export default function Asynchronous() {
  const [open, setOpen] = React.useState(false);
  const [options, setOptions] = React.useState([]);
  const loading = open && options.length === 0;


  const onChangeHandle = async value => {
// this default api does not support searching but if you use google maps or some other use the value and post to get back you reslut and then set it using setOptions 
    console.log(value);

    const response = await fetch(
      "https://country.register.gov.uk/records.json?page-size=5000"
    );

    const countries = await response.json();
    setOptions(Object.keys(countries).map(key => countries[key].item[0]));
  };

  React.useEffect(() => {
    if (!open) {
      setOptions([]);
    }
  }, [open]);

  return (
    <Autocomplete
      id="asynchronous-demo"
      style={{ width: 300 }}
      open={open}
      onOpen={() => {
        setOpen(true);
      }}
      onClose={() => {
        setOpen(false);
      }}
      getOptionSelected={(option, value) => option.name === value.name}
      getOptionLabel={option => option.name}
      options={options}
      loading={loading}
      renderInput={params => (
        <TextField
          {...params}
          label="Asynchronous"
          variant="outlined"
          onChange={ev => {
            // dont fire API if the user delete or not entered anything
            if (ev.target.value !== "" || ev.target.value !== null) {
              onChangeHandle(ev.target.value);
            }
          }}
          InputProps={{
            ...params.InputProps,
            endAdornment: (
              <React.Fragment>
                {loading ? (
                  <CircularProgress color="inherit" size={20} />
                ) : null}
                {params.InputProps.endAdornment}
              </React.Fragment>
            )
          }}
        />
      )}
    />
  );
}