Advanced React Native: How useEffect Cleanup Function Works

Application Development 25-Jan-2023

Explaining how useEffect cleanup function works with a real-world example.

This subject is very important for React Native or React developers, but recently I saw quite a number of React developers who do not use the wonderful thing called cleanup function in useEffect hook, so I decided to write a post about that and show you my friends, a real-world example.


This article is for developers with a basic knowledge of the useEffect hook function.

React allows us to create actions on the component mount or while the component is updated by the use of useEffect hook with the array of dependencies.

It takes two parameters. The first parameter is a function. The second parameter is an array of dependencies. If any dependency changes, then the effect will run again.

//Run after component mounted/first rendered.
useEffect(()=>{},[])//Run after dep1 or dep2 change/updated.
useEffect(()=>{},[dep1, dep2])

The useEffect function has one more responsibility, and this is for the cleanup function that runs after the component is unmounted.

//Run after component is unmounted/removed
return ()=>{}

Why Use Cleanup Function

This is the main question that we need to ask ourselves before using it because we need to know its exact purpose.

This cleanup function that useEffect offers us is for letting us clean or remove any processes or actions that are not relevant when the component is unmounted or not shown anymore.

Example for action that runs after the component is unmounted.

//When the component will unmounted,
//The console will print "Component unmounted"useEffect(()=> {
return ()=> {
console.log("Component unmounted");

Real World Example

I will illustrate the importance of the cleanup function with a real-world example that can prevent leak of memory and bad performance.

Let’s assume that we have an application to which we want to add a new component that shows the loading text with 3 dots that builds the dots one after another until we receive the response from the server.

For example:

Loading” and after 1 sec -> “Loading.” and after 1 sec -> “Loading..” and after 1 sec -> “Loading…” and so on until we receive the response from the API request.

The Loading Component

This component will include the useEffect hook with the cleanup function, let’s build the component.

const Loading = ()=> {
const [dots, setDots] = useState<string>(".");
const dotsLoading = () => {
setDots((state)=>(state.length === 3 ? '' : `${state}.`));
};useEffect(() => {
//1000 ms = 1 sec
const 1Sec = 1000;
const intervalId = setInterval(dotsLoading, 1Sec);
return () => clearInterval(intervalId);
}, []);return (
<View style={Styles.modal}>

This Loading component now can be included in any screen component that makes an API request and shows this Loading component while it fetches/post data from/to the server.

The Screen Component

This Screen component will contain an API request to show the Loading component while we wait for the data to be received from the server.

Let’s build the component.

import Loading from "./components/Loading;
import { fetchData } from "./API;const Screen = ()=> {
const [isLoading, setIsLoading] = useState<boolean>(false); useEffect(()=>{
async ()=>{
const result = await fetchData();
},[])return (
{isLoading && <Loading />}

As you can see, we have Screen component that on mount creates an API request with fetchData function inside useEffect.

In the beginning, we make the Loading component visible and now the Loading component is shown until we receive the data from the server, in addition, the async function is to await for the fetchData function response.

When the isLoading parameter is false, the cleanup function inside the Loading component is run and it clears the interval and stops the loop. By doing it this way, we protect our app from running the dotsLoading function even if we no longer use the Loading component (when we receive the data from the API request).

In Conclusion

The cleanup function of useEffect is very powerful and with a good understanding of it, we can save our application from bad performance and memory leakage.

Source: JavaScript in Plain English