Search code examples
javascriptreactjsreact-hooksaxios

How do I make a single request to a second API in React using a useState set in the first API request


So I'm first making a call to my API to get and store user information, but then I need to make a second call to the API to get secondary information based on the response data from the first call.

I've tried a couple of ways to do this, and one of the ways does work, but not really in an acceptable way.

Here's the relevant constants:

const thisUserID = localStorage.getItem('userID');

const [ listnames, setListNames ] = useState(null);
const [ listID, setListID ] = useState(null);
const [ listcontent, setListContent ] = useState(null);

The first call to the API:

useEffect(() => {
        axios.get(`/lists/user/${thisUserID}`)
            .then((response) => {
                console.log(response.data[0].listName);
                console.log(response.data[0]._id);
                setListNames(response.data[0].listName);
                setListID(response.data[0]._id);
            })
            .catch((err) => {
                console.error(err);
            });
    }, []);

I tried using a second useEffect() for the second call like so:

useEffect(() => {
        console.log("listID = " + listID)
        axios.get(`/listcontent/user/${listID}`)
            .then((response) => {
                console.log(response.data);
                setListContent(response.data);
            })
            .catch((err) => {
                console.error(err);
            });
    }, []);

But listID that was set in the first useEffect is null.

I tried using an if statement to only run when listID had a value like this:

if (listID) {
        console.log("listID = " + listID)
        axios.get(`/listcontent/user/${listID}`)
        .then((response) => {
            console.log(response.data);
            setListContent(response.data);
        })
        .catch((err) => {
            console.error(err);
        });
    }

This works and successfully calls the API and returns with the data I want, but it is making constant requests to the API multiple times a second, I just need it to make one single request.

So I tried to add a second condition to the if statement like this:

    let sss = 0;

    if (listID && sss < 1) {
        sss = 1;
        console.log("listID = " + listID)
        axios.get(`/listcontent/user/${listID}`)
        .then((response) => {
            console.log(response.data);
            setListContent(response.data);
        })
        .catch((err) => {
            console.error(err);
        });
        console.log("sss = " + sss)
    }

But it just kept making continuous calls to the API, even though the console log showed sss as 1 (or any number I set).

As a last attempt I tried adding a useEffect in the if statement, but that was never going to work and didn't.

I haven't been using React for very long, but I feel like there's gotta be a relatively simple way I'm missing or just don't know about to do this, because people surely do things like this often. If anyone can see where I'm making a mistake(s) or knows how I can go about solving this, I appreciate any help. If there's any more information/code I can provide that could be helpful please let me know, thank you.


Solution

  • Add ListId as a dependency in the second useEffect.

    useEffect(() => {
      console.log("listID = " + listID);
      if (listID) {
        axios
          .get(`/listcontent/user/${listID}`)
          .then((response) => {
            console.log(response.data);
            setListContent(response.data);
          })
          .catch((err) => {
            console.error(err);
          });
      }
    }, [listID]);