DEV Community

Cover image for React useEffect cleanup: How and when to use it

React useEffect cleanup: How and when to use it

Martín Mato on May 14, 2020

Did you ever got the following error? Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memor...
Collapse
 
radoncreep profile image
radoncreep

I am just coming from the react docs trying to figure this out I couldn't get their explanation but this!!! Well explained, came across the same error now i understand why and Ik how to fix it. Thank you!

Collapse
 
otamnitram profile image
Martín Mato

Happy to help!

Collapse
 
kavehkarami profile image
Kaveh Karami • Edited

Thanks for the solution on Axios request.
I have a question.
I'm using an instance of Axios and in this instance, you cant be able to use instanceAxios.CancelToken.source() so I gotta import Axios too.
is there another way to use CancelToken.source() in the instance of Axios like instanceAxios.CancelToken.source()?

Collapse
 
otamnitram profile image
Martín Mato

As far as I know axios by design, cancelToken won't be part of the instance. You may be able to do something similar to this.

const axios = require('axios');
const source = axios.CancelToken.source();
const instance = axios.create();
instance.get('/foo', { cancelToken: source.token });
Enter fullscreen mode Exit fullscreen mode
Collapse
 
oscarlofwenhamn profile image
oscar.lofwenhamn

Thanks a bunch, that cleared things up! Time to add some let mounted=... to my effects..

Collapse
 
jimmybutton profile image
Samuel Liedtke

Many thanks, this was really helpful! I got this error "Warning: An update to SomeComponent inside a test was not wrapped in act(...)." when running my tests. Took me a while to figure out this was coming from a fetch() call in a useEffect() method that was updating some state. Applied the "only update state when mounted" fix you suggested and that solved it.

Collapse
 
maskedman99 profile image
Rohit Prasad

Thanks for the solution on axios request.
I had thought of looking into the warning before, but kept procrastinating it. Now I just need to go and apply the fix :)

Collapse
 
otamnitram profile image
Martín Mato

Glad it was helpful for you

Collapse
 
irfan profile image
irfan

hii here i'm not performing any async operation event though i'm still getting warnings with cleanup function when i'm routing to another page. Please can you suggest me any solution.

export default function useOnScreen(ref, rootMargin = "0px") {
const [isVisible, setIsVisible] = useState(false)
useEffect(() => {
let setRef=null;
if (ref.current === null) return
const observer = new IntersectionObserver(
([entry]) => setIsVisible(entry.isIntersecting),
{ rootMargin }
)
observer.observe(ref.current)
setRef=ref
return () => {
if (setRef.current) {
observer.unobserve(setRef.current)
}
}
}, [ref, rootMargin])

return isVisible
}

Collapse
 
kamo profile image
KAIDI

Nice explanation, thnks

Collapse
 
obkurucu_ profile image
ozankurucu

Thank you this was unbelievable!

Collapse
 
mkumar100 profile image
mkumar100

Excellent

Collapse
 
voralagas profile image
Pravin Poudel

there migh be fetchUsers() instead of fetchData() in axios abort code.

Thank you for the great content !!

Collapse
 
samx23 profile image
Sami Kalammallah

Thank you, it solves my clean up definition issue :)

Collapse
 
neshatademi profile image
Neshat

Very nice simple and clear explanation. Was trying to figure it out in the react docs but this made my day. ✌️

Collapse
 
otamnitram profile image
Martín Mato

Happy to help!

Collapse
 
prakudag profile image
Praveen Danagoudru

let mounted....... is awesome :)

Collapse
 
kwadoskii profile image
Austin Ofor

Thanks, this helped me.

Collapse
 
dadeke profile image
Deividson Damasio

Thank you very much! 😀👍

Collapse
 
bronxsystem profile image
bronxsystem

the axios thing helped me out a lot thats really cool thank you.

Collapse
 
paras594 profile image
Paras 🧙‍♂️

awesome !!...very well explained

Collapse
 
andresavellan profile image
Andres Avellan

Thanks, nice article.

What about putting setloading(true) in the return function?
ex.
return function cleanup() {
setloading(true);
}
Would it differ from mounted = false? and why?
Thank you in advance.

Collapse
 
trex777 profile image
Manish Kumar Sahu

Thanks Man! This is quite helpful.

Collapse
 
oleksiiivanov profile image
Oleksii Ivanov

Thanks for details.

Collapse
 
krankj profile image
Sudarshan K J

Thanks! It is very well written. Even novices like me could understand it fully.

Collapse
 
krankj profile image
Sudarshan K J

In the last axios example, shouldn't the method call be fetchUsers() and not fetchData()?

Collapse
 
radoncreep profile image
radoncreep

yes. it should be fetchUsers()

Collapse
 
prodanov17 profile image
prodanov17 • Edited

I use useEffect to call a function which calls the api via axios only on the initial render. I don’t get any errors, do I still need to unsubscribe and do all this?

Collapse
 
jontatan25 profile image
jontatan25

Thank you!! Thanks to this article I finally understand what this is about and what the use case could be. Saludos!

Collapse
 
padarcsaba profile image
Csaba Padar

In the last eample (Extra: Cancel an Axios request)

There is a typo: Before the cleanup function, it should be "fetchUsers()" instead "fetchData()"

Good article, tho! Thanks!

Collapse
 
hosseinfalah profile image
HosseinFalah

prefect

Collapse
 
robertommm profile image
RobertoMMM

Noice