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:
useEffect
works fine. The proof is here https://codesandbox.io/s/set-seasons-9e5cvn?file=/src/App.js. So, the problem is ingetSeasonList
function.await useSeasonService()
won't work. React Hooks names start withuse
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- Your code example doesn't show what
state
is and how it's initialized. state && state?.seasonList
check is redundant.state?.seasonList
is enough.- 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.