Home > Software design >  Define Async Function outside useEffect and don't include it in the dependency array
Define Async Function outside useEffect and don't include it in the dependency array

Time:01-02

Hi please I need help for clarifying the following:

It is about doing an API call only one time, when the component is mounted.

I know that we must never do something like this in React:

Case 1:

useEffect(async () => {
    const response = await callAPI();
    setData(response.data);
}, []);

I know that the problem of Case 1 is that useEffect is expecting a function and not a promise (since async functions are always of type Promise), also I know that the return callback of useEffects is not going to work properly.

I also know that these 2 possible solutions work:

Case 2:

useEffect(()=> {
  const fetchData = async () => {
    const response = await callAPI();
    setData(response.data);
  }
  fetchData();
}, []);

Case 3:

const fetchData = useCallback(async () => {
   const response = await callAPI();
   setData(response.data);
},[]);

useEffect(()=> {
  fetchData();
}, [fetchData]);

My main question here is what about Case 4 and Case 5, what is wrong with them?, I have many projects where I'm using it in that way. Thanks.

Case 4:

const fetchData = async () => {
   const response = await callAPI();
   setData(response.data);
}

useEffect(()=> {
  fetchData();
}, []);

Case 5:

const fetchData = useCallback(async () => {
   const response = await callAPI();
   setData(response.data);
},[]);

useEffect(()=> {
  fetchData();
}, []);

By the way I know that in Case 4 fetchData function is going to be re-defined in every re-render, sometimes that is not a big problem, specially if the function is not added in the dependency array of useEffect, since that avoids calling fetchData multiple times.

CodePudding user response:

Case 4 and also Case 5 In short, their return value is a promise They basically create the same result as Case 1

I personally like to use iife like this :

    useEffect(() => {
        (async () => {
            const res = await fetch(`${URL}people`)
            const data = await res.json()
            setPepoleArr(data)
        })()

    }, [])

Think of it this way once async is added The function returns a promise, The question is where she returns him

CodePudding user response:

Nothing is wrong with them, other than perhaps the superfluous useCallback in case 5. Also a linter might might not like that you're calling function in an effect that is not in the dependency array, but that's a failure of the linting heuristic not an actual problem.

There is another pattern that avoids both, though: Define the function outside of the component

async function fetchData() {
   const response = await callAPI();
   return response.data;
}

and then just use

useEffect(() => {
  fetchData().then(setData);
}, [])

CodePudding user response:

When you want to get a request from the server and use async & await, it takes a few seconds for the data to be given to you. When you setState at the same time, it doesn't give you data

const fetchData = async () => { const response = await callAPI(); if (response) setData(response.data);enter code here` }

useEffect(()=> { fetchData(); }, []);`

  • Related