Open In App

How To Avoid Infinite Loops When Using useEffect() in ReactJS?

Last Updated : 14 Oct, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

useEffect() can lead to infinite loops, causing performance issues or crashes if not used correctly. In this article, we will explain what causes these infinite loops and how to avoid them when working with useEffect() in ReactJS.

Avoid infinite loops in useEffect() by providing appropriate dependencies in the dependency array. Use an empty array for one-time execution, a specific state value for triggering effect, or multiple state values with conditions for selective execution.

Prerequisites

To Avoid Infinite Loops When using the useEffect() in ReactJS we have these approaches:

Steps To Avoid Infinite Loops When Using useEffect()

Step 1: Create a React project:

npx create-react-app appname

Step 2: After creating your project folder i.e. appname, move to it using the following command:

cd appname

Project Structure

Now, we will see some examples to avoid or prevent the infinite loops when using the useEffect() hook with a different approach.

Approach 1: Using Empty Dependency Array

In this example, we are fetching data from an API using the useEffect hook. We pass an empty array as the dependency array, which means that the hook will only be called once after the component mounts.

If we didn’t specify any dependencies, the hook would be called after every render, causing an infinite loop. By specifying the empty array as the dependency, we ensure that the hook is only called once, and we avoid any performance issues or crashes.

Step to Install axios module:

npm i axios

The updated dependencies in package.json file.

"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.6.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}

Example: Below example demonstrates how to avoid infinite loops when using the useEffect hook in React.

JavaScript
// Filename - App.js

import React, {
    useState,
    useEffect
} from 'react';

import axios from 'axios';

function App() {
    const [data, setData] = useState([]);
    const [loading, setLoading] = useState(false);

    useEffect(() => {
        setLoading(true);

        axios.get(
            'https://...com/posts')
            .then((response) => {
                setData(response.data);
                setLoading(false);
            })
            .catch((error) => {
                console.log(error);
                setLoading(false);
            });
    }, []); // This is the dependency array

    if (loading) {
        return <p>Loading data...</p>;
    }

    return (
        <div>
            <center>
                <h1 style={{ color: 'green' }}>
                    GeeksforGeeks
                </h1>
                <h3>
                    How to avoid infinite loop when 
                    using useEffect hook in React
                </h3>
            </center>
            <h3>Posts</h3>
            <ul>
                {data.map((post) => (
                    <li key={post.id}>
                        <h2>{post.title}</h2>
                        <p>{post.body}</p>
                    </li>
                ))}
            </ul>
        </div>
    );
}

export default App;


To start the application run the following command.

npm start

Output: This output will be visible on the http://localhost:3000 on the browser window.

Avoid Infinite Loops When Using useEffect() in ReactJS

Approach 2: Using Memoization

In this example, we are using the useCallback hook to memoize the handleClick function. This function is passed down to the ChildComponent as a prop, so we want to ensure that it is only re-created when its dependencies change. We pass an empty array as the dependency array, which means that the function is only created once.

Example: Below example demonstrates how to avoid infinite loops using memoization in the useEffect hook in React.

JavaScript
// Filename - App.js

import React, {
    useState,
    useEffect,
    useCallback
} from 'react';

function ChildComponent({ onClick }) {
    return <button onClick={onClick}>Click me</button>;
}

function App() {
    const [count, setCount] = useState(0);

    const handleClick = useCallback(() => {
        console.log('Clicked!');
    }, []); // This is the dependency array

    useEffect(() => {
        console.log('Count changed!');
    }, [count]);

    return (
        <div>
            <center>
                <h1 style={{ color: 'green' }}>
                    GeeksforGeeks
                </h1>
                <h3>
                    How to avoid infinite loop when 
                    using useEffect hook in React
                </h3>
            </center>
            <h1>
                Count: {count}
            </h1>
            <ChildComponent onClick={handleClick} />
            <button onClick={() => setCount(count + 1)}>
                Increment count
            </button>
        </div>
    );
}

export default App;


To start the application run the following command.

npm start

Output: This output will be visible on the http://localhost:3000 on the browser window.

Avoid Infinite Loops When Using useEffect() in ReactJS



Similar Reads