Okay, I have something here I don't quite understand, so I'll be thankful if someone can explain. I have this useEffect hook which calls two async functions that retrieve data from an API. You can see the difference between the two is that setQuestions() is not in a cleanup function on the second screenshot. Now, the code works as I expect when setQuestions() is in the cleanup function and I'm not sure why. I figured i'm creating some side effect that's causing rerenders, which then causes the hook to run multiple times and break the code. So can someone explain why does it need to be inside the cleanup function and what exactly is happening when it isn't?
#Why do I need the cleanup function?
24 messages · Page 1 of 1 (latest)
Are you SURE it works as expected when the setQuestions() call is IN the cleanup function? It really shouldn't... I'd be interested to see your entire code here.
It shouldn't work at all (basically) since the questions would only be fetched at unmount (since there's an empty dependency array) making me wonder just what's happening with the App component...
And if you're wondering why your "not in a cleanup function" variant doesn't work it's because your getData() call is async so the setQuestions() on line 18 is going to set the questions to a promise reference instead of your question data.
It should be:
useEffect(() => {
const getData = async () => {
const sessionToken = await getToken();
const data = await getQuestions(sessionToken);
localStorage.setItem('token', sessionToken);
setQuestions(data)
// WHOA nelly! You've not set questions so you're
// effectively resetting questions to the current
// state of questions which is an empty array...
//return questions;
};
getData();
}
i'm already doing all of this inside getData (look at the screenshot), I'm just calling it inside useEffect
There really isn't any other logic inside the app component that might break it (at least I don't think so) but here it is
You're missing the critical step of calling setQuestions()...
I'm calling setQuestions() in useEffect... or am I missing something?
You're calling it only as part of the cleanup code... See my previous post about where this should be.
Yes, I saw that. Inside the cleanup function it actually works. If I put it out as you've shown outside the cleanup function, the hook triggers multiple times.
Not really... the effect only gets triggered on mount so should only happen once. If you mean the component itself gets re-rendered then yes... Did you try my code?
yes, it rerenders and the API returns with 429 too many requests, like in my example without the cleanup function
Something's not adding up here... do you have a link to a Scrim or a GitHub repo with your code so I can debug it?
sure, I'll put it on github and send a link
👍
Ok, I'll take a look!
Ok, the 429 is NOT 429 requests - it's an error code because opentdb has a rate limit...
I'm sending you a PR with the working code (I've added a simple dump of the questions so you can see them)... standby
Ok, PR created with working useEffect
fwiw here's a screen shot with the dump of REAL questions:
If opentdb is rate limited to 1 request every 5 seconds... 429 is the error code that comes back here:
Thank you, I think I get it now but also useEffect triggers twice. Isn't it supposed to trigger only once? What's the deal here?
That's because of <StrictMode> in your main.jsx...