首页 > 解决方案 > 使用 React 从 API 自动完成的异步请求

问题描述

React 代码仅适用于某些 api 请求示例当我尝试从http://www提取数据时,我能够从https://country.register.gov.uk/records.json?page-size=5000提取数据。 omdbapi.com/?apikey= {api_key}&s= 我收到一个类型错误,下面是工作代码。但是数据库在 Json 文件中有不同的格式。我尝试了不同的方法来解决,但无法破译解决方案。希望有人能发光。

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 res = await response.json();

      if (active) {
        setOptions(Object.keys(res).map(key => res[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"
          fullWidth
          variant="outlined"
          InputProps={{
            ...params.InputProps,
            endAdornment: (
              <React.Fragment>
                {loading ? <CircularProgress color="inherit" size={20} /> : null}
                {params.InputProps.endAdornment}
              </React.Fragment>
            ),
          }}
        />
      )}
    />
  );
}

工作 JSON

[
  {
    "PT": {
      "index-entry-number": "147",
      "entry-number": "147",
      "entry-timestamp": "2016-04-05T13:23:05Z",
      "key": "PT",
      "item": [
        {
          "country": "PT",
          "official-name": "The Portuguese Republic",
          "name": "Portugal",
          "citizen-names": "Portuguese"
        }
      ]
    }

]

在此处获取类型错误

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('http://www.omdbapi.com/?apikey={api_key}=');

            await sleep(1e3);
            const res = await response.json();
            console.log(res);
            if (active) {

             setOptions(Object.keys(res).map(key => res[key].Search[0]));

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

    React.useEffect(() => {
        if (!open) {
            setOptions([]);
        }
    }, [open]);

    return (
        <Autocomplete
            id="tags-outlined"
            style={{ width: 300 }}
            open={open}
            onOpen={() => {
                setOpen(true);
            }}
            onClose={() => {
                setOpen(false);
            }}
            getOptionSelected={(option, value) => option.Title === value.Title}
            getOptionLabel={option => option.Title}
            options={options}
            loading={loading}
            renderInput={params => (
                <TextField
                    {...params}
                    label="Asynchronous"
                    fullWidth
                    variant="outlined"
                    InputProps={{
                        ...params.InputProps,
                        endAdornment: (
                            <React.Fragment>
                                {loading ? <CircularProgress color="inherit" size={20} /> : null}
                                {params.InputProps.endAdornment}
                            </React.Fragment>
                        ),
                    }}
                />
            )}
        />
    );
}

不工作的Json

{
  "Title": "Guardians of the Galaxy Vol. 2",
  "Year": "2017",
  "Rated": "PG-13",
  "Released": "05 May 2017",
  "Runtime": "136 min",
  "Genre": "Action, Adventure, Comedy, Sci-Fi",
  "Director": "James Gunn",
  "Writer": "James Gunn, Dan Abnett (based on the Marvel comics by), Andy Lanning (based on the Marvel comics by), Steve Englehart (Star-Lord created by), Steve Gan (Star-Lord created by), Jim Starlin (Gamora and Drax created by), Stan Lee (Groot created by), Larry Lieber (Groot created by), Jack Kirby (Groot created by), Bill Mantlo (Rocket Raccoon created by), Keith Giffen (Rocket Raccoon created by), Steve Gerber (Howard the Duck created by), Val Mayerik (Howard the Duck created by)",
  "Actors": "Chris Pratt, Zoe Saldana, Dave Bautista, Vin Diesel",
  "Plot": "The Guardians struggle to keep together as a team while dealing with their personal family issues, notably Star-Lord's encounter with his father the ambitious celestial being Ego.",
  "Language": "English",
  "Country": "USA",
  "Awards": "Nominated for 1 Oscar. Another 12 wins & 42 nominations.",
  "Poster": "https://m.media-amazon.com/images/M/MV5BNjM0NTc0NzItM2FlYS00YzEwLWE0YmUtNTA2ZWIzODc2OTgxXkEyXkFqcGdeQXVyNTgwNzIyNzg@._V1_SX300.jpg",
  "Ratings": [
    {
      "Source": "Internet Movie Database",
      "Value": "7.6/10"
    },
    {
      "Source": "Rotten Tomatoes",
      "Value": "84%"
    },
    {
      "Source": "Metacritic",
      "Value": "67/100"
    }
  ],
  "Metascore": "67",
  "imdbRating": "7.6",
  "imdbVotes": "513,275",
  "imdbID": "tt3896198",
  "Type": "movie",
  "DVD": "22 Aug 2017",
  "BoxOffice": "$389,804,217",
  "Production": "Walt Disney Pictures",
  "Website": "N/A",
  "Response": "True"
}

错误

Unhandled Rejection (TypeError): Cannot read property '0' of undefined

类型错误

 35 | console.log(res);
  36 | if (active) {
  37 |     // setOptions(Object.keys(movies).map(key => key.results[{}]));
> 38 |     setOptions(Object.keys(res).map(key => res[key].Search[0]));
     | ^  39 |     // setOptions(options.movies.map(results => results));
  40 |     console.log(Object.keys)
  41 | }

标签: reactjsapifetch

解决方案


推荐阅读