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

Posted

技术标签:

【中文标题】Reactjs - 通过在自动完成组件(材料 UI)中的每个输入更改上点击 API 来更新选项【英文标题】:Reactjs - Update options by hitting API on every input change in Autocomplete component (Material UI) 【发布时间】:2020-09-10 04:25:33 【问题描述】:

我是 Reactjs 的初学者。我想创建一个自动完成组件,在每次输入更改时都会触发 API 并相应地更新选项。我正在使用 Material UI 提供的自动完成组件。据我了解,here 给出的示例会访问一次 API 并在本地对其进行过滤。我尝试使用材质组件提供的 InputChange 道具。我还发现了这个分析器 - https://***.com/a/59751227/8090336。但无法找出正确的方法。

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;

【问题讨论】:

【参考方案1】:

我遇到过这个问题,我在用户输入时手动调用 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>
            )
          
        />
      )
    />
  );



【讨论】:

我不确定这是否完全回答了@gowtham-bhat 的问题。他们使用搜索 API 并在用户输入时传递更新的查询字符串值(注意使用 debounce)。相反,您提供的解决方案会预先缓存所有结果并在 UI 中进行过滤。 @ChrisBricker 是的,我已经回答了如何在文本字段中的每个值更改时调用 API。对于不同的情况,构建查询字符串可能会有所不同。 onChangeHandle 函数那里传递了一个值,即用户输入的值使用它来构建您的查询字符串。

以上是关于Reactjs - 通过在自动完成组件(材料 UI)中的每个输入更改上点击 API 来更新选项的主要内容,如果未能解决你的问题,请参考以下文章

创建组件后,reactJS 材料 ui 中的平滑崩溃损坏

React js材料ui自动完成芯片,里面有一个按钮

如何在反应材料-ui自动完成中实现最小字符长度功能

数据变化时如何在ReactJS中刷新Material-Table(Material-ui)组件

移除 React Material ui 组件中自动完成的下划线样式

Reactjs - 如何在 reactjs 材料表中加载和映射数据