I have this simple example that's giving me grief:
useEffect(() => {
axios.get(...).then(...).catch(...)
}, [props.foo])
warning: can't perform a react state update on an unmounted component
Done some research and this one is more understandable. TypeScript seems not to like that approach as useEffect
should return a void.
useEffect(() => {
let isSubscribed = true
axios.get(...).then(...).catch(...)
return () => (isSubscribed = false)
}, [props.foo])
TypeScript:
/**
* Accepts a function that contains imperative, possibly effectful code.
*
* @param effect Imperative function that can return a cleanup function
* @param deps If present, effect will only activate if the values in the list change.
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#useeffect
*/
function useEffect(effect: EffectCallback, deps?: DependencyList): void;
How to implement an isSubscribed
in my useEffect
with TS?
Thanks.
useEffect
itself returns void
, but the function provided to useEffect
is typed as EffectCallback
. This is definied as:
// NOTE: callbacks are _only_ allowed to return either void, or a destructor.
// The destructor is itself only allowed to return void.
type EffectCallback = () => (void | (() => void | undefined));
Source
This means your effect callback can actually return a function, which has to return void
or undefined
.
Now you can solve your issue to avoid calling setState
with the isSubscribed
variable. But another (maybe better) way is to outright cancel the request.
useEffect(() => {
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('...', { cancelToken: source.token }).then(/**/).catch(e => {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {/* handle error */}
});
return () => source.cancel();
}, [props.foo])
This is also documented in the README.
The problem with your current code is, that your destructor function returns the boolean isSubscribed
. Instead of returning it, just put the assignment into a function body:
return () => {
isSubscribed = false;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With