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

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

programmeradmin1浏览0评论

I am a beginner in Reactjs. I want to create an Autocomplete component where on every input change the API is hit and the options are updated accordingly. I am using the Autocomplete component provided by Material UI. As I understand, the example given here hits an API once and filters it locally. I tried using the InputChange props provided by material component. Also I found this anser - . But can't figure out the right way.

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('='+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;

I am a beginner in Reactjs. I want to create an Autocomplete component where on every input change the API is hit and the options are updated accordingly. I am using the Autocomplete component provided by Material UI. As I understand, the example given here hits an API once and filters it locally. I tried using the InputChange props provided by material component. Also I found this anser - https://stackoverflow.com/a/59751227/8090336. But can't figure out the right way.

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;
Share Improve this question edited May 24, 2020 at 5:41 gowthz asked May 23, 2020 at 9:39 gowthzgowthz 4692 gold badges10 silver badges25 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 17

I had faced this problem I manually called the API when ever the user types in. find the link for the sandbox. Check the onChange prop for the textfield rendered inside the autocomplete

// *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>
            )
          }}
        />
      )}
    />
  );
}


与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论