4 ms·
> If you want something to execute once initially you can use useEffect with an empty dependency list, but note that then there’s no way of accessing updates va
by mrighele 5y ago
> If you want something to execute once initially you can use useEffect with an empty dependency list, but note that then there’s no way of accessing updates values (in callbacks) and everything will reflect the initial state. Often you’ll have to use useRef just to keep track of the current state. Or maybe useState?
I'm not sure if I understood what you mean, but note that useState accepts not only the updated state, but also a function that takes the current state as argument and return the updated state.
In other words, instead of something like this
useEffect( async () => {
...
const someValue = await someFunction();
setState({...state, someValue });
}, [... ] );
you should use something like this
useEffect( async () => {
...
const someValue = await someFunction();
setState( currentState => ({...currentState, someValue }));
}, [ ... ] );
(the example is with async but it is the same for regular callbacks)
- ricardobayes 5y agoYou can use a boolean ref for this in the useEffect to keep track whether it was the first render or not. https://reactjs.org/docs/hooks-faq.html#can-i-run-an-effect-only-on-updates https://reactjs.org/docs/hooks-faq.html#can-i-run-an-effect-...
- jakelazaroff 5y agoNote that you shouldn’t (can’t?) actually pass an async function directly to useEffect, since it returns a promise: https://github.com/facebook/react/issues/14326 https://github.com/facebook/react/issues/14326
- jacobedawson 5y agoNot true, see Gaeron's direct reply in the thread you linked to, that's been the standard for 3 years and works like a charm - useEffect specifically is the hook for handling async functions ("impure effects").
- azangru 5y agoNotice the words "pass to useEffect" in the parent comment, and the code snippet in the grandparent they are commenting on. The type of the callback function that useEffect accepts is () => void rather than () => Promise<unknown>. What's not true about that?
- jakelazaroff 5y agoI reworded it to make it a bit more clear (at least, I thought so) — "pass an async function to useEffect", meaning the argument supplied to useEffect itself, rather than "use directly within" which is ambiguous. Re-added "directly" to hopefully make even more clear. Sorry for the confusion!
- mrighele 5y agoyou're right, good catch. Usually it's the TS compiler that prevents me doing that.
- zebnyc 5y agoI usually use an IIFE to encapsulate the async block inside the useEffect. Works like a charm!
- tanaypingalkar 5y agoTrue, you cannot do that in useEffect, it will throw you error. And probably your linter will tell you. You can't even use your own or third party hooks in side useEffect. This also throw error I don't know why?
- gassiss 5y agoBecause you could be nesting hooks, which would bring all sorts of weird behavior.