首页 > 解决方案 > 使用带有 useEffect 的 Material-UI 自动完成

问题描述

我正在尝试使用 Material-UI Autocomplete 制作搜索组件。

我面临的问题是来自 API 的数据不会重新加载。因此,当我加载时,它会获取结果,但是,如果我更改输入,它不会发出另一个请求。

我尝试在 onChange 函数中调用 api 函数,但它仍然没有做任何事情。

我还是 React Hooks 的新手,任何反馈都将不胜感激。

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 [input_var, setInput] = React.useState("");
  const loading = open && options.length === 0;

  const api = React.useEffect(() => {
    let active = true;

    if (!loading) {
      return undefined;
    }

    (async () => {
      var response = await fetch(`${baseUrl}/users?q=${input_var}`, {
        method: "get",
        headers: {
          "Content-Type": "application/json",
          Authorization: auth
        }
      });
      await sleep(1e3); // For demo purposes.
      const countries = await response.json();
      console.log(countries);
      countries.items.map((item) => console.log(item.name));
      if (active) {
        setOptions(countries.items);
      }
    })();

    return () => {
      active = false;
    };
  }, [loading, input_var]);

  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={async (newValue) => {
            await api;
            await setInput(newValue);
          }}
          InputProps={{
            ...params.InputProps,
            endAdornment: (
              <React.Fragment>
                {loading ? (
                  <CircularProgress color="inherit" size={20} />
                ) : null}
                {params.InputProps.endAdornment}
              </React.Fragment>
            )
          }}
        />
      )}
    />
  );
}

标签: javascriptreactjsreact-hooksmaterial-uiuse-effect

解决方案


推荐阅读