0

I am new to React and I was not able to find any solution for my problem. I am loading the first get request successfully then I take a random element from the array with lodash and with that info I can create a new URL but I am unable to create an array with the exact same method I have used for the first API call. Please someone could help me out how can I create a new axios.get request?

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>
  );
}
BizzyBob
  • 12,309
  • 4
  • 27
  • 51
  • It's not clear what you problem is. Do you get an error from your second axios request? – tromgy Oct 02 '21 at 13:05
  • After the second React.useEffect I have this error : React Hook "React.useState" is called conditionally. React Hooks must be called in the exact same order in every component render. – Ritmillio X Oct 02 '21 at 13:06

4 Answers4

1

Notes:

1- Always use React hooks at the top.

2- If the second get depened on the first one, then it should be inside then of the first request because Axios is sending the request asynchronously.

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>;
}

Output:

enter image description here

Abdulmuhaymin
  • 905
  • 7
  • 16
0

You are using selectedRegion value before it is even initialized because an empty input in useEffect [] means that react will call it immediately after component has mounted. You need to make the second get request after the first one has been resolved or the component has updated (Lifecycle Methods) This can give a little more clarity
componentDidMount equivalent on a React function/Hooks component?

tanmya
  • 73
  • 7
0

you need to use selectedRegion as a dependency for useEffect hook. so the hook will be called every time you change the selectedRegion.

example,

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"));
Dev-2019
  • 547
  • 3
  • 11
0

here's the React way to do this

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>
Siddharth
  • 543
  • 6
  • 15