Home > other >  react useEffect with async-await not working as expected
react useEffect with async-await not working as expected

Time:03-16

I have a useEffect hooks in my component, which makes a API call and I want it to run only on first render. But I'm unable to make the API call. what am I missing here?

  useEffect(() => {
    //should run on first render
    (async () => {
      const getAllSeasons = await getSeasonList();
      setSeasons(getAllSeasons);
    })();
  }, []);

  const getSeasonList = async () => {
    if (state && state?.seasonList) {
      return state?.seasonList;
    } else {
      const seasonData = await useSeasonService();
      if (seasonData?.status === "loaded") {
        return seasonData?.payload?.seasons || [];
      } else if (seasonData.status == "error") {
        return [];
      }
    }
  };

CodePudding user response:

Best way to fetch APIs using fetch method

fetch('https://apisaddress.me/api/')
  .then(({ results }) => consoe.log(results) ));

Another aproach is using axios

const Func= async ()=>{
   const response= await axios.get('https://pokeapi.co/api/v2/pokemon? 
   limit=500&offset=200')
   this.setState({Data:response.data.results})
}


// npm install axios

CodePudding user response:

Make the new function and clean all code from useEffect and put inside that function. and then call the function inside the useEffect. Like:

const sampleCall = async () => {
  const getAllSeasons = await getSeasonList();
  setSeasons(getAllSeasons);
}
useEffect(() => {
  sampleCall()
}, [])

Follow these steps, if it is still not working then try to add seasons inside the useEffect array, [seasons]. Thank You.

CodePudding user response:

I don't see any issue in your code but just sharing few more ways to achieve your need.

WITHOUT ASYNC

useEffect(() => {
  getSeasonList().then((response) => {
     setSeasons(response);
  });
}, []);

WITH ASYNC

useEffect(() => {
  const fetchApi = async () => {
    const seasonList = await getSeasonList();
    setSeasons(seasonList);
  }

  fetchApi()
}, []);

EDITED

Looking at your whole implementation, looks like you don't really need to use async wait multiple times


useEffect(() => {
 const fetchSeasonList = async () => {
   const seasonData = await useSeasonService()

   if (seasonData?.status === 'loaded') {
     setSeasons(seasonData?.payload?.seasons || [])
   } else if (seasonData.status == 'error') {
     setSeasons([])
   }
 }

 if (!state?.seasonList) {
    fetchSeasonList()
 }
 
}, [])

CodePudding user response:

  1. useEffect works fine. The proof is here https://codesandbox.io/s/set-seasons-9e5cvn?file=/src/App.js. So, the problem is in getSeasonList function.
  2. await useSeasonService() won't work. React Hooks names start with use word and can't be called inside functions or conditionally. useSeasonService is considered by React engine as a custom hook. Chek this for more details: https://reactjs.org/docs/hooks-custom.html#extracting-a-custom-hook
  3. Your code example doesn't show what state is and how it's initialized.
  4. state && state?.seasonList check is redundant. state?.seasonList is enough.
  5. It's a bad practice to put such complex logic as in getSeasonList into React components. You'd better use some state container (Recoil might be a good choice if you have some small non-related states in the app).

P.S. You wrote a poor description of the problem and then gave minuses for answers. That's not fair. Nobody would help you if you'll continue to do such thing. You gave 4 minuses and received 4 minuses in response. It's better to clarify what's wrong before giving a plus or minus to any answer.

  • Related