Passing an empty array as the second argument to useEffect makes it only run on mount and unmount, thus stopping any infinite loops.

useEffect(() => {
  setIngredients({});
}, []);

This was clarified to me in the blog post on React hooks at https://www.robinwieruch.de/react-hooks/

Answer from WhiteFluffy on Stack Overflow
Top answer
1 of 16
231

Passing an empty array as the second argument to useEffect makes it only run on mount and unmount, thus stopping any infinite loops.

useEffect(() => {
  setIngredients({});
}, []);

This was clarified to me in the blog post on React hooks at https://www.robinwieruch.de/react-hooks/

2 of 16
135

Had the same problem. I don't know why they not mention this in docs. Just want to add a little to Tobias Haugen answer.

To run in every component/parent rerender you need to use:

  useEffect(() => {

    // don't know where it can be used :/
  })

To run anything only one time after component mount(will be rendered once) you need to use:

  useEffect(() => {

    // do anything only one time if you pass empty array []
    // keep in mind, that component will be rendered one time (with default values) before we get here
  }, [] )

To run anything one time on component mount and on data/data2 change:

  const [data, setData] = useState(false)
  const [data2, setData2] = useState('default value for first render')
  useEffect(() => {

// if you pass some variable, than component will rerender after component mount one time and second time if this(in my case data or data2) is changed
// if your data is object and you want to trigger this when property of object changed, clone object like this let clone = JSON.parse(JSON.stringify(data)), change it clone.prop = 2 and setData(clone).
// if you do like this 'data.prop=2' without cloning useEffect will not be triggered, because link to data object in momory doesn't changed, even if object changed (as i understand this)
  }, [data, data2] )

How i use it most of the time:

export default function Book({id}) { 
  const [book, bookSet] = useState(false) 

  const loadBookFromServer = useCallback(async () => {
    let response = await fetch('api/book/' + id)
    response  = await response.json() 
    bookSet(response)
  }, [id]) // every time id changed, new book will be loaded

  useEffect(() => {
    loadBookFromServer()
  }, [loadBookFromServer]) // useEffect will run once and when id changes


  if (!book) return false //first render, when useEffect did't triggered yet we will return false

  return <div>{JSON.stringify(book)}</div>  
}
🌐
Reddit
reddit.com › r/reactjs › useeffect causes an infinite loop?
r/reactjs on Reddit: useEffect causes an infinite loop?
January 21, 2023 -

Hey!! First time building a website and have ran into this issue when trying to fetch content from Sanity Studio.

Here's the link: https://pastebin.com/3iL0gpBt

Copying what I think is the relevant part of the code

export default function IssuesList() {
  const [items, setItems] = useState([]);

  useEffect(() => {
    sanityClient
      .fetch(
        `*[_type == "issue"] | order(publishedAt desc) {
      title,
      slug,
      description,
      frontCover{
        asset->{
          _id,
          url
        }
      }
    }`
      )
      .then((data) => {
        setItems(data);
      })
      .catch(console.error);
  });

  return (
    <div css={issuesListSx}>
      <Frame path={[{ name: "Issues", slug: "/issues" }]}>
        <Grid gap={2} columns={[1, null, 2]} className="issuesGrid">
          {items.map((issue) => {
            return (
              <div className="issueItem" key={issue.title}>
                <Link to={"/issues/" + issue.slug.current}>
                  <div>{issue.title}</div>
                  {issue.frontCover && "asset" in issue.frontCover && (
                    <img src={issue.frontCover.asset.url} alt="" />
                  )}
                </Link>
              </div>
            );
          })}
        </Grid>
      </Frame>
    </div>
  );
}

E: Fixed!! Had to add an empty array as a second parameter to useEffect

Discussions

react query select causing useEffect infinite loop
But it is causing infinite loop · TestComponent: const ITEMS = [] const [totalItems, setTotalItems] = useState(ITEMS) const { fetchTestData } = useFetchHook() useEffect(() => { if (fetchTestData.data != null) { const dataItems = [...ITEMS] dataItems[0].value = fetchTestData.data .x ... More on github.com
🌐 github.com
1
1
July 1, 2022
Yet another useEffect()-causing-infinte-loop when fetching from API post. But Whyyyy?
Posts shouldn’t be in the dependency list of the useEffect since your effect isn’t dependent on posts state in any way The state change updates posts which then calls the effect again, which then calls the api, hence the loop. The fetch method will be the dependency of the useEffect and the fetch method has to be wrapped in useCallback to ensure stable reference More on reddit.com
🌐 r/react
30
10
September 2, 2022
useEffect update on state change without infinite loop?

You're super close! useEffect doesn't always require a dependency. Leave it blank and it'll only load once, similar to componentDidMount. Take a look at the following. In the case to rerun useEffect on state change you'll likely want to use a second state that isn't the state for data or use props from a parent component. Hopefully that'll steer you in the right direction.

useEffect(() => { axios.get('https://example.com/api') .then(res => { setData(res.data); }) .catch(err => { // Handle error }) }, []);

More on reddit.com
🌐 r/reactjs
8
1
February 19, 2021
Fetch method in useEffect is in infinite loop - javascript
I was getting the infinite loop of the code getting executed, but I couldn't find where the problem was. As I am new with react I sometimes struggle to see the problem. Could it be the dependency o... More on stackoverflow.com
🌐 stackoverflow.com
December 7, 2022
🌐
Max Rozen
maxrozen.com › learn-useeffect-dependency-array-react-hooks
Preventing infinite re-renders when using useEffect and useState - Max Rozen
import React, { useEffect, useState } from 'react'; export default function DataDisplayer() { const [data, setData] = useState(''); useEffect(() => { const getData = async () => { const response = await fetch(`https://swapi.dev/api/people/1/`); const newData = await response.json(); setData(newData); }; getData(); // highlight-next-line }, []); //<-- This is the dependency array if (data) { return <div>{data.name}</div>; } else { return null; } } What if you wanted to let users decide which id they wanted to query, and forgot to add the dependency array? You'd cause an infinite loop. import Re
🌐
Medium
medium.com › @andrewmyint › infinite-loop-inside-useeffect-react-hooks-6748de62871
How to Fix the Infinite Loop Inside “useEffect” (React Hooks)
June 4, 2023 - Inside “fetchUser”, it will update the state “name” on line 9. Then it will trigger the component to re-render again. As a result, “useEffect()” will run again and update the state.
🌐
LogRocket
blog.logrocket.com › home › how to solve the react useeffect hook’s infinite loop patterns
How to solve the React useEffect Hook's infinite loop patterns - LogRocket Blog
June 4, 2024 - Since the reference value of the person object changes on every render, React re-runs useEffect · As a result, this invokes setCount on every update cycle. This means that we now have an infinite loop
🌐
Dmitri Pavlutin
dmitripavlutin.com › react-useeffect-infinite-loop
How to Solve the Infinite Loop of React.useEffect()
February 26, 2023 - Type some words into the input... ... No infinite loop is created. That's a win! useEffect(callback, deps) is the hook that executes callback (the side-effect) after deps changes....
🌐
Indersingh
indersingh.com › node › 584
useEffect is Executed in an endless loop react function component | Inder Singh - Drupal Frontend Developer | India
Doing this will solve the infinite loop problem:- const [data, setData] = useState(null); const [login, setLogin] = useState("githubusername"); useEffect(() => { console.log('useEffect()') fetch(`https://api.github.com/users/${login}`) .then(res => res.json()) .then(setData) .catch(console.error); });
Find elsewhere
🌐
freeCodeCamp
freecodecamp.org › news › prevent-infinite-loops-when-using-useeffect-in-reactjs
How to Prevent Infinite Loops When Using useEffect() in ReactJS
April 26, 2023 - One common mistake that can cause infinite loops is not specifying a dependency array. useEffect checks if the dependencies have changed after every render of the component. So, when no dependencies are provided, the effect will run after every single render, which can lead to a continuous loop of updates if state is being updated.
🌐
YouTube
youtube.com › watch
Why useEffect causes infinite loops - fix it with useCallback - YouTube
Just a little example of how to fix an infinite useEffect loop caused by fixing a eslint exhaustive-deps warning------------🔔 Newsletter http://eepurl.com/...
Published   May 18, 2022
🌐
egghead.io
egghead.io › lessons › javascript-perform-asynchronous-actions-like-fetching-http-data-in-react-with-useeffect
Run Side Effects with React useEffect | egghead.io
useEffect(() => { console.log(props.id) ... useEffect. Otherwise you could end up with an infinite loop as the useEffect will run every time the component in re-rendered....
🌐
Reddit
reddit.com › r/react › yet another useeffect()-causing-infinte-loop when fetching from api post. but whyyyy?
r/react on Reddit: Yet another useEffect()-causing-infinte-loop when fetching from API post. But Whyyyy?
September 2, 2022 -

Hi,

I read similar Reddit posts, googled a solution but I couldn't figure out why useEffect is doing an infinite loop so I'm hoping that Reddit will help me. Here's a code:

const [posts, setPosts] = useState([]);

const fetchData = async () => {

const response = await fetch(url);

const data = await response.json();

setPosts(data);

console.log(data)

}

useEffect(() => {

fetchData();

}, [posts]);

  • By looking at the console, I can see that the console.log is called infinitely.

  • Here's a screenshot of the console. You can see that I'm fetching an array with objects (not an object).

  • I tried fetch without async/await. Same result.

  • I know that I won't have an issue if useEffect has an empty dependency array, but I want it to update the results on the page automatically if I create a new post or delete a post (I'm fetching results from my local WordPress).

  • Not sure why, but I don't think having posts.length as dependency is the right solution.

What am I doing wrong?

🌐
Reddit
reddit.com › r/reactjs › useeffect update on state change without infinite loop?
r/reactjs on Reddit: useEffect update on state change without infinite loop?
February 19, 2021 -

The code:

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

function Foo() {
  const [data, setData] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const response = await axios('api_here');

      setData(response.data);
    };
    fetchData();
  }, [data]);

  return <>{console.log(data)}</>;
}

export default Foo;

Currently, the above snippet results in a infinite loop. I understand why: the culprit is setData(\`response.data``). How can I fix it but still getfetchDatato run on changes to the state living indata? Doing so only when the component is mounted is straightforward, changeuseEffectsecond argument to[]`. But how to run it on state change?

Things I tried:

  1. Compare response.data with data and return early if they are equal:

[snip]
const response = await axios('api_here');
if (response.data === data) return;
[snip]

No difference, infinite loop.

2. Put object in the state and pass its values to useEffect:

[snip]
const [data, setData] = useState([]);
[snip]

[snip]
    fetchData();
  }, [Object.values(data)]);
[snip]

Infinite loop is still there, and now React is complaining as well:

React Hook useEffect has a missing dependency: 'data'. Either include it or remove the dependency array

React Hook useEffect has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked

3. Using [data.length] instead of [data]:

[snip]
    fetchData();
  }, [data.length]);
[snip]

The above sort of works - no more infinite loop. But, as I understand it, useEffect will only be re-run if the length of data will change, not necessarily when the values will be modified without altering the length of it. And React is complaining about missing dependency: 'data' as well.

I'm merely beginner in JS / React world and don't have other ideas how to solve this. Any help will be greatly appreciated!

🌐
DEV Community
dev.to › arikaturika › the-traps-of-useeffect-infinite-loops-836
The traps of useEffect() - infinite loops - DEV Community
January 14, 2021 - If you look at the useEffect() hook you will see that its first argument is a function (our effect) that will make the API call. The second argument is the dependency array, which in our case it's empty and it means we only want the effect to run once, after the component has rendered the first time (mounted). While doing data fetching, it happened that I forgot to provide the second argument to the hook (the dependency array).
🌐
JavaScript in Plain English
javascript.plainenglish.io › 5-useeffect-infinite-loop-patterns-2dc9d45a253f
5 useEffect Infinite Loop Patterns | by Naveen DA | JavaScript in Plain English
July 23, 2021 - If the useEffect is triggering the callback only when the dependencies are changes, why we ended with an infinite loop here. You need to take into account important another mantra of React which is “When state or Props is changing, the component will re-render”. In this code, we set the ...
🌐
GitHub
github.com › remix-run › remix › discussions › 3657
useFetcher causing an infinite loop in useEffect with fetcher in dependency array · remix-run/remix · Discussion #3657
I don't think that's the best way to use fetchers. useEffect is fine for initial load, but remember that fetchers go through multiple state changes, and once it's done. You can't reset the state, but you can call load/submit again. change month/year · trigger effect · fetcher loads · fetcher state changes · trigger effect · fetcher loads · infinite loop ·
Author   remix-run
🌐
CodingDeft
codingdeft.com › posts › react-useeffect-infinite-loop
How to solve Infinity loop in React's useEffect | CodingDeft.com
Here as well, you will end up in an infinite loop. You could prevent it by putting a condition inside the useEffect to check if data does not exist. If it doesn't, then only fetch the data and update the state:
🌐
Andreas Reiterer
andreasreiterer.at › home › why is my useeffect hook executed in an endless loop?
Why is my useEffect Hook executed in an endless loop? » Andreas Reiterer
February 12, 2019 - if we didn’t add all dependencies, they give some error like below, “React Hook useEffect has missing dependencies: ‘XXXXX’, ‘XXXXX’, and ‘XXXX’. Either include them or remove the dependency array” ... It’s the only way I’ve found to stop the endless loop.