【问题标题】:material-ui useAutocomplete with asynchronusmaterial-ui useAutocomplete 与异步
【发布时间】:2020-06-15 18:40:03
【问题描述】:

我正在尝试将 material-ui useAutocomplete 与异步调用一起使用。 autocomplete 的简单案例可以工作,但我需要调整输入焦点时显示的对话框,所以我必须使用 useAutocomplete

所以我尝试合并此代码(异步):https://codesandbox.io/s/pvjgx

使用这个(使用自动完成):https://codesandbox.io/s/261pd?file=/demo.js

问题是我不知道在哪里或如何将onChange 输入到我的输入中,以便我可以触发获取数据的异步函数

这是我目前得到的无效代码(无效沙箱)https://codesandbox.io/s/material-demo-gl9pw?file=/demo.js

import React from "react";
import useAutocomplete from "@material-ui/lab/useAutocomplete";

import { InputBase } from "@material-ui/core";
import CircularProgress from "@material-ui/core/CircularProgress";

import styled from "styled-components";

import { makeStyles } from "@material-ui/core/styles";

const Listbox = styled("ul")`
  width: 300px; margin: 2px 0 0;padding: 0;position: absolute; list-style: none; background-color: #fff;overflow: auto;max-height: 250px; border-radius: 4px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); z-index: 1;
  & li {padding: 5px 12px; display: flex; & span {flex-grow: 1; }& svg { color: transparent; } }
  & li[aria-selected="true"] { background-color: #fafafa; font-weight: 600; & svg {color: #1890ff;}}
  & li[data-focus="true"] {background-color: #e6f7ff; cursor: pointer; & svg { color: #000; } }
`;

const useStyles = makeStyles(theme => ({
  autoWidth: {width: "auto"},
  input: {
    marginLeft: theme.spacing(1),
    flex: 1,
    color: "white",
    textAlign: "center",
    align: "center",
    "& input": {
      textAlign: "center"
    }
  },
  iconButton: {
    padding: 10,
    color: "white"
  },
  searchRoot: {
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    backgroundColor: "blue"
  }
}));

export default function MyAutocomplete() {
  const classes = useStyles();

  const [value, setValue] = React.useState("");
  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; }

    console.log("run")(async () => {
      const response = await fetch("https://country.register.gov.uk/records.json?page-size=5000");
      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]);

  const {
    getRootProps, getInputLabelProps, getInputProps, getListboxProps, getOptionProps, groupedOptions, focused, setAnchorEl
    // value
  } = useAutocomplete({
    id: "customized-autocomplete-async",
    options: options,
    getOptionLabel: option => option.name
  });

  return (
    <div className={classes.autoWidth}>
      <div {...getRootProps()}>
        <InputBase
          {...getInputProps()}
          //value={value}
          //onChange={event => {setValue(event.target.value);          }}
          inputRef={setAnchorEl}
          className={classes.input}
          placeholder="Localisation"
          inputProps={{ "aria-label": "Localisation" }}
          fullWidth={true}
          endAdornment={
            <React.Fragment>
              {loading ? <CircularProgress color="inherit" size={20} /> : null}
            </React.Fragment>
          }
        />
      </div>
      {focused && (
        <div className={classes.autoWidth}>
          <Listbox {...getListboxProps()}>
            <div> Localiser moi ! </div>
            <br />
            {groupedOptions.map((option, index) => (
              <li {...getOptionProps({ option, index })}>
                <span>{option.title}</span>
              </li>
            ))}
          </Listbox>
        </div>
      )}
    </div>
  );
}

欢迎任何提示

【问题讨论】:

    标签: material-ui


    【解决方案1】:

    您在问题中复制了两次相同的链接,所以我真的不知道您想要实现什么。 我正在使用带有 TextField 输入的自动完成功能:

                    <Autocomplete
                        options={ isValidating ? [{nickname: '...loading'}] : data ? data : [] }
                        getOptionLabel={(option) => option.nickname}
                        id="auto-complete"
                        autoComplete
                        includeInputInList
                        value={value}
                        onChange={(event, newValue) => {
                        setValue(newValue);
                        }}
                        onInputChange={(event, newInputValue) => {
                           console.log(newInputValue);
                          }}
                        renderInput={(params) => <TextField {...params} error={error} helperText={error} label="Email Address or User ID" value={query} onChange={handleChange} margin="normal" />}
                />
    

    并使用Swr拉取数据:

        const [query, setQuery] = React.useState('');
        const [value, setValue] = React.useState()
        const [loading, setLoading] = React.useState(false)
    
        const { data, isValidating } = useSwr(active && query.length > 2 ? '/api/getusers?q='+query : '', fetcher)
    
        const handleChange = (event) => {
          setQuery(event.target.value);
        };
    

    一切都在异步运行。

    也许尝试进一步澄清您的问题,以便我可以改进我的答案:)

    【讨论】:

    • 我不能直接使用自动完成,因为我需要显示其他信息,按钮是显示的对话框,所以我必须使用 useautocomplete
    猜你喜欢
    • 2021-07-02
    • 2018-01-10
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 2020-07-12
    • 2019-11-14
    • 2019-07-19
    相关资源
    最近更新 更多