React - 多个 Axios 请求

Posted

技术标签:

【中文标题】React - 多个 Axios 请求【英文标题】:React - Multiple Axios request 【发布时间】:2021-11-23 18:21:55 【问题描述】:

我是 React 新手,我无法找到任何解决我的问题的方法。我正在成功加载第一个获取请求,然后我使用 lodash 从数组中获取一个随机元素,并使用该信息创建一个新 URL,但我无法使用与第一个 API 调用完全相同的方法创建一个数组.请有人可以帮助我如何创建新的 axios.get 请求?

import axios from "axios";
import React from "react";
import _ from 'lodash';

export default function App() 

  const baseURL = "http://apiv3.iucnredlist.org/api/v3/region/list?token=9bb4facb6d23f48efbf424bb05c0c1ef1cf6f468393bc745d42179ac4aca5fee";
  const [list, setList] = React.useState(0);
  const [error, setError] = React.useState(0);

  //get List of available regions
  React.useEffect(() => 
    axios.get(baseURL).then((response) => 
      setList(response.data);
    ).catch(error => 
      setError(error);
    )
  , []);

  if (error) return `Error: $error.message`;
  if (!list) return null;

  //Take a random region from the list
  const randomRegion = _.sample(list.results);
  console.log(randomRegion)

  //Load the list of all species in the selected region
  const selectedRegion = "http://apiv3.iucnredlist.org/api/v3/species/region/"+ randomRegion.identifier + "/page/0?token=9bb4facb6d23f48efbf424bb05c0c1ef1cf6f468393bc745d42179ac4aca5fee"
  console.log(selectedRegion)

  const [speciesList, selectedRegionList] = React.useState(0);
  
  React.useEffect(() => 
    axios.get(selectedRegion).then((response) => 
      selectedRegionList(response.data);
    ).catch(error => 
      setError(error);
    )
  , []);

  return (
    <div>
     
    </div>
  );

【问题讨论】:

不清楚你的问题是什么。您的第二个 axios 请求是否出现错误? 在第二个 React.useEffect 之后我有这个错误:有条件地调用 React Hook "React.useState"。在每个组件渲染中,必须以完全相同的顺序调用 React Hooks。 【参考方案1】:

注意事项:

1- 始终在顶部使用 React 钩子。

2- 如果第二个依赖于第一个,那么它应该在第一个请求的then 内,因为 Axios 正在异步发送请求。

import axios from "axios";
import React from "react";
import _ from "lodash";

export default function App() 
  const baseURL =
    "http://apiv3.iucnredlist.org/api/v3/region/list?token=9bb4facb6d23f48efbf424bb05c0c1ef1cf6f468393bc745d42179ac4aca5fee";
  const [list, setList] = React.useState(0);
  const [error, setError] = React.useState(0);
  const [speciesList, selectedRegionList] = React.useState(0);

  //get List of available regions
  React.useEffect(() => 
    axios
      .get(baseURL)
      .then((response) => 
        setList(response.data);
        //Take a random region from the list
        const randomRegion = _.sample(response.data["results"]);
        //Load the list of all species in the selected region
        const selectedRegion =
          "http://apiv3.iucnredlist.org/api/v3/species/region/" +
          randomRegion.identifier +
          "/page/0?token=9bb4facb6d23f48efbf424bb05c0c1ef1cf6f468393bc745d42179ac4aca5fee";
        getOneRegion(selectedRegion);
      )
      .catch((error) => 
        setError(error);
      );
  , []);

  function getOneRegion(url) 
    axios
      .get(url)
      .then((response) => 
        selectedRegionList(response.data);
        console.log(response.data);
      )
      .catch((error) => 
        setError(error);
      );
  

  if (error) return `Error: $error["message"]`;
  if (!list) return null;

  if (speciesList)
    return (
      <>
        <h1>speciesList["region_identifier"]</h1>
        <h2>Count: speciesList["count"]</h2>
      </>
    );
  return <div></div>;

输出:

【讨论】:

【参考方案2】:

您甚至在初始化之前就使用了 selectedRegion 值,因为 useEffect [] 中的空输入意味着 react 将在组件安装后立即调用它。您需要在第一个解决或组件更新后发出第二个获取请求(生命周期方法) 这样可以更清楚一点componentDidMount equivalent on a React function/Hooks component?

【讨论】:

【参考方案3】:

您需要使用 selectedRegion 作为 useEffect 挂钩的依赖项。 所以每次更改 selectedRegion 时都会调用钩子。

例子,

import React,  useEffect, useState  from "react";
import ReactDOM from "react-dom";

const regions = ["region1", "region2", "region3"];

export default function App() 
  const [selectedRegion, setSelectedRegion] = useState(0);

  useEffect(() => 
    // api call
    console.log(regions(regions[selectedRegion]));
  , [selectedRegion]);

  return (
    <div>
      <button onClick=() => setSelectedRegion((current) => current + 1)>
        change region
      </button>
    </div>
  );


ReactDOM.render(<App />, document.getElementById("container"));

【讨论】:

【参考方案4】:

这是 React 的方法

const App = () => 
  const [list, setList] = React.useState();
  const [speciesList, setSpeciesList] = React.useState();
  const [error, setError] = React.useState(0);
  const baseURL = "http://apiv3.iucnredlist.org/api/v3/region/list?token=9bb4facb6d23f48efbf424bb05c0c1ef1cf6f468393bc745d42179ac4aca5fee";

  // get List of available regions
  React.useEffect(() => 
    function fetchdata() 
      axios
        .get(baseURL)
        .then(response => 
          const list = response.data
          setList(list); // got first list
          console.log(list)

          if (!list) return null;

          //Take a random region from the list
          const randomRegion = _.sample(list.results);
          console.log(randomRegion)

          //Load the list of all species in the selected region
          const selectedRegion = "http://apiv3.iucnredlist.org/api/v3/species/region/" + randomRegion.identifier + "/page/0?token=9bb4facb6d23f48efbf424bb05c0c1ef1cf6f468393bc745d42179ac4aca5fee"
          console.log(selectedRegion)

          axios
            .get(selectedRegion)
            .then((response) => 
              const selectedRegionList = response.data
              setSpeciesList(selectedRegionList) // here'e data for the region
              console.log("data count:", selectedRegionList.count)
            ).catch(error => 
              setError(error);
            )

        )
        .catch(error => setError(error))
    

    fetchdata()
  , []);

  return <div / > ;


ReactDOM.render( < App / > , document.getElementById('root'))
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<div id="root"></div>

【讨论】:

以上是关于React - 多个 Axios 请求的主要内容,如果未能解决你的问题,请参考以下文章

Axios在react js中获取请求时出错

React,如何在 axios 请求的对象中对数组进行包含

React之配置多个代理实现数据请求返回

React中Axios请求的问题

取消路由更改请求 (React/Redux/Axios)

React - Axios 调用发出过多请求