【问题标题】:React JS Material UI Autocomplete: Change OptionsReact JS Material UI 自动完成:更改选项
【发布时间】:2020-08-07 05:29:39
【问题描述】:

我想为我的 React JS 项目使用自动完成字段。对于 UI 的设计,我使用 Material UI。在文档中,您可以看到以下示例:

<Autocomplete
                    required
                    id="combo-box-demo"
                    filterOptions={(x) => x}
                    value={this.state.departure}
                    options={top100Films}
                    getOptionLabel={(option) => option.title}
                    renderInput={(params) => <TextField {...params} label="Startpunkt" variant="outlined" />}
                />

选项对象具有以下默认值:

let top100Films = [
        { title: 'The Shawshank Redemption', year: 1994 },
        { title: 'Monty Python and the Holy Grail', year: 1975 },
    ];

出于我的目的,我想动态更改选项,因为我使用了一个 Rest API 来获取输入的结果。因此,我的问题是如何在用户输入时动态更改选项。

【问题讨论】:

  • 您想从 API 获取结果吗?或者您想为之前获取的结果添加过滤器?当用户输入时。
  • @joyson 我想从 API 中获取结果。当用户键入时,我想将新结果提取到选项中。
  • 您找到解决方案了吗?我也在找一样的

标签: javascript reactjs autocomplete material-ui


【解决方案1】:

您可以在您的情况下使用 onInputChange 道具:

      <Autocomplete
            required
            id='combo-box-demo'
            filterOptions={(x) => x}
            value={this.state.departure}
            options={top100Films}
            getOptionLabel={(option) => option.title}
            onInputChange={(event: object, value: string, reason: string) => {
              if (reason === 'input') {
                changeOptionBaseOnValue(value);
              }
            }}
            renderInput={(params) => (
              <TextField {...params} label='Startpunkt' variant='outlined' />
            )}
          />

然后你可以定义 changeOptionBaseOnValue 来处理你的选项。

【讨论】:

    【解决方案2】:

    你可以看看这个例子:

    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';
    
    function sleep(delay = 0) {
      return new Promise((resolve) => {
        setTimeout(resolve, delay);
      });
    }
    
    export default function Asynchronous() {
      const [open, setOpen] = React.useState(false);
      const [options, setOptions] = React.useState([]);
      const loading = open && options.length === 0;
    
      React.useEffect(() => {
        let active = true;
    
        if (!loading) {
          return undefined;
        }
    
        (async () => {
          const response = await fetch('https://country.register.gov.uk/records.json?page-size=5000');
          await sleep(1e3); // For demo purposes.
          const countries = await response.json();
    
          if (active) {
            setOptions(Object.keys(countries).map((key) => countries[key].item[0]));
          }
        })();
    
        return () => {
          active = false;
        };
      }, [loading]);
    
      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"
              InputProps={{
                ...params.InputProps,
                endAdornment: (
                  <React.Fragment>
                    {loading ? <CircularProgress color="inherit" size={20} /> : null}
                    {params.InputProps.endAdornment}
                  </React.Fragment>
                ),
              }}
            />
          )}
        />
      );
    }
    

    Source

    【讨论】:

    • 这不会在输入时获取数据,这只会进行一次 api 调用以一次获取所有选项,这不是所要求的
    【解决方案3】:

    我通过使用文本字段中的 OnChange 和调用 findAddresses 函数的 handleAddressChange 函数来执行此作为地址搜索/验证的一部分。 findAddresses 使用 Axios 调用 API,然后保存这些结果并将它们显示为自动完成中结果的选项。

    这是我的代码的简化版本:

    import React, { useState, ChangeEvent } from 'react';
    import {
      TextField,
      InputAdornment
    } from "@material-ui/core";
    import Autocomplete from '@material-ui/lab/Autocomplete';
    import { Search } from "@material-ui/icons";
    import axios from "axios";
    
    const AddressSearch = (props) => {
    
      const [addressesList, setAddressesList] = useState([]);
      const [inputAddress, setInputAddress] = useState<string>("");
    
      const handleAddressChange = (event: ChangeEvent<{ value: unknown }>) => {
        setInputAddress(event.target.value as string);
        findAddresses(event.target.value as string);
      };
    
      const baseUrl = 'https://api.website.com/';
    
      const findAddresses = (text?: string) => {
        let params = `Key=value`
        if (!!text) {
          params += (`&Text=` + text);
          let addressesResponse;
    
          return (
            axios.get(baseUrl + params)
              .then(response => {
                addressesResponse = response.data.Items
                if (!Array.isArray(addressesResponse) || !addressesResponse.length) {
                  return;
                }
                setAddressesList(addressesResponse);
              })
              .catch(error => console.log(error))
          )
        }
      }
    
      return (
        <div>
          <Autocomplete
            id="address-autocomplete"
            freeSolo
            options={addressesList}
            getOptionLabel={(option) => option.Text}
            popupIcon={<Search />}
            renderInput={(params) => <TextField 
                                        id="address-input"                          
                                        {...params} 
                                        onChange={handleAddressChange}
                                        placeholder="Quickly find your address" 
                                        InputProps={{ ...params.InputProps,
                                          startAdornment: (
                                            <InputAdornment position="start"><Search /></InputAdornment>
                                          )
                                        }}
                                      /> }
          />
        </div>
      );
    }
    
    export default AddressSearch;

    【讨论】:

      猜你喜欢
      • 2020-07-16
      • 1970-01-01
      • 1970-01-01
      • 2020-03-12
      • 1970-01-01
      • 2021-03-05
      • 2021-12-13
      • 2022-11-30
      • 2021-06-05
      相关资源
      最近更新 更多