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(); }, []);`