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

Bug: Infinite loop with useState and useEffect hooks
I am using default pattern for updating state if props changes. React version: 18.2.0 Steps To Reproduce Create component with useState and useEffect and some prop with array Update state value on ... More on github.com
🌐 github.com
9
January 26, 2024
React useEffect infinite loop despite empty array
I have a react hook. This hook has sub-hooks, that when generated, generate for themselves an ID. This ID is always unique, as it is simply increased by 1 each time a new sub-hook is created. const... More on stackoverflow.com
🌐 stackoverflow.com
December 6, 2020
node.js - Is there any way to stop the useEffect infinite loop even after provided with second empty array argument? - Stack Overflow
I am try to call dispatch method from useEffect hook in my React app but after rendering the useEffect continue looping. More on stackoverflow.com
🌐 stackoverflow.com
reactjs - useEffect dependency array causing infinite loop - Stack Overflow
Either include it or remove the ... is an empty array when I console log it. But when I pass in data to the dependency array, I do get the correct API response in the console, but I get an infinite loop. From what I've read, this is one of the most common traps to fall into when using useEffect, but I still have a hard time wrapping my head around how to resolve this or finding an answer I can truly understand. Any help would be appreciated in what is currently wrong with my code, and ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
GitHub
github.com › facebook › react › issues › 15096
Infinite loop in useEffect using blank object or array · Issue #15096 · facebook/react
March 13, 2019 - function Example() { const [count, setCount] = useState(0); const [foo, setFoo] = useState({}); useEffect(() => { console.log("Infinite Loop"); setCount(100); // doesn't cause infinite loop. // but this does // setFoo({}); // or setFoo([]); }); return <div />; } I don't know if it's a bug or default behaviour because in earlier version of react (in v16.7.0-alpha.0), both string and number also causing infinite loop which seems to be fixed in latest one.
Author   eashish93
🌐
DEV Community
dev.to › oyedeletemitope › three-ways-to-cause-infinite-loops-when-using-useeffect-in-react-and-how-to-prevent-them-3ip3
Three Ways to Cause Infinite Loops When Using UseEffect in React and How to Prevent Them - DEV Community
November 17, 2024 - If you check the result in the ... continuously: To prevent this infinite loop, you need to provide a dependency array that includes the values on which the effect depends....
🌐
Max Rozen
maxrozen.com › learn-useeffect-dependency-array-react-hooks
Preventing infinite re-renders when using useEffect and useState - Max Rozen
The dependency array in useEffect lets you specify the conditions to trigger it. If you provide useEffect an empty dependency array, it'll run exactly once, as in this example (CodeSandbox link):
🌐
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 - Furthermore, notice that we passed ... our function in an infinite loop · To get rid of your infinite loop, simply use an empty dependency array like so:...
🌐
Medium
medium.com › @andrewmyint › infinite-loop-inside-useeffect-react-hooks-6748de62871
How to Fix the Infinite Loop Inside “useEffect” (React Hooks)
June 4, 2023 - ... “You can tell React to skip applying an effect if certain values haven’t changed between re-renders. To do so, pass an array as an optional second argument to useEffect”, from the official documentation.
Find elsewhere
🌐
DEV Community
dev.to › manojms › how-to-fix-useeffect-hook-executing-in-an-endless-loop-1oga
How to Fix useEffect Hook executing in an endless loop? - DEV Community
October 16, 2021 - This is even mentioned in the official React Hooks API documentation: If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty >array ([]) as a second argument.
🌐
CodingDeft
codingdeft.com › posts › react-useeffect-infinite-loop
How to solve Infinity loop in React's useEffect | CodingDeft.com
The useEffect hook runs again as we did not pass any dependency array to it and causes an infinite loop. To fix this, we can pass an empty array [] as a dependency to the useEffect hook:
🌐
GitHub
github.com › facebook › react › issues › 28109
Bug: Infinite loop with useState and useEffect hooks · Issue #28109 · facebook/react
January 26, 2024 - Add default value for prop as empty array · Do not pass value via prop in the component · Link to code example: https://codesandbox.io/p/sandbox/beautiful-http-n4c3p5 · export default function App() { return ( <div className="App"> <List ...
Author   mkozachok
🌐
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.
🌐
Perficient Blogs
blogs.perficient.com › 2024 › 12 › 16 › avoiding infinite loops when utilizing useeffect() in reactjs
Avoiding Infinite Loops When Utilizing useEffect() in ReactJS / Blogs / Perficient
December 16, 2024 - This cycle repeats indefinitely, ... runs after every re-render of the component. To prevent this issue, include an empty dependency array....
🌐
GeeksforGeeks
geeksforgeeks.org › how-to-avoid-infinite-loops-when-using-useeffect-in-reactjs
How To Avoid Infinite Loops When Using useEffect() in ReactJS? | GeeksforGeeks
October 14, 2024 - 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 ...
Top answer
1 of 2
2

First things first,

I would like to be able to create several of SomeComponent from within App in the future.

This (at least the way you're doing it) is not something that is possible or should be done at all when using React. You cannot create a component inside another component.

The reason your useEffect is in an infinite loop can be all sorts of things at the moment. It can be that it is not positioned in the highest scope, but my guess is that the following happens:

genId() is called, and state is updated, re-render is initialized (because of state update), and const SomeComponent = () => {...} is initialized again, thus activating useEffect again.

To fix this, first things first remove <SomeComponent /> from being created inside <App /> They should be completely separated. Secondly, pass the genId function as a prop, and add it to useEffect dependency list, since you need it there.

This would be a great start since now the code is semantically and by the rules correct.

const SomeComponent = ({ genId }) => {
  const [ componentId, setComponentId ] = React.useState(null);
    
  React.useEffect(() => {
    let generatedId = genId();
    setComponentId(generatedId);
    console.log(`generated '${generatedId}'`)
  }, [genId]);
    
  return <div>nothing works</div>
}


const App = () => {
  const [ idCounter, setIdCounter ] = React.useState(0);
  
  
  const genId = () => {
    setIdCounter( id => id + 1 );
    return `ID-${idCounter}`;
  }
  
  
  return <SomeComponent genId={genId} />
};
2 of 2
1

I wont answer this but just make the point having sub-components have some disadvantages. You sub-componeentn is almost imposible to unit test. Maybe you can move it to top level componennt and accept generatedId as a prop

const SomeComponent = ({generatedId}) => {
    const [ componentId, setComponentId ] = React.useState(null);

    React.useEffect(() => {

      setComponentId( id => generatedId );
      console.log(`generated '${generatedId}'`)
    }, []);

    return <div>nothing works</div>
}

const App = () => {
  const [ idCounter, setIdCounter ] = React.useState(0);
  
  
  const genId = () => {
    setIdCounter( id => id + 1 );
    return `ID-${idCounter}`;
  }
  

  
  return <SomeComponent  generatedId={genId()}/>
};
🌐
DEV Community
dev.to › collegewap › how-to-solve-infinity-loop-in-reacts-useeffect-5d6e
How to solve Infinity loop in React's useEffect? - DEV Community
March 28, 2023 - The useEffect hook runs again as we did not pass any dependency array to it and causes an infinite loop. To fix this, we can pass an empty array [] as a dependency to the useEffect hook:
🌐
Plain English
plainenglish.io › blog › 5-useeffect-infinite-loop-patterns-2dc9d45a253f
5 useEffect Infinite Loop Patterns
July 23, 2021 - We need to specify the dependencies as the empty array. According to official docs, it is not safe to omit the dependencies · useEffect uses shallow object comparison to determine, whether the data was changed or not.
🌐
Stack Overflow
stackoverflow.com › questions › 65869466 › is-there-any-way-to-stop-the-useeffect-infinite-loop-even-after-provided-with-se
node.js - Is there any way to stop the useEffect infinite loop even after provided with second empty array argument? - Stack Overflow
@DrewReese it's only mount once when I inspected the console after rendered e.g it mount once for useEffect(() => console.log('Mount'), []) but infinite loop for useEffect(() => dispatch(getCategories()), [])
🌐
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 - Animation showing process of an infinite loop caused by useEffect · This happened because there isn't any dependency array specified, indicating that the effect should be run every time after the component re-renders.
🌐
Dmitri Pavlutin
dmitripavlutin.com › react-useeffect-infinite-loop
How to Solve the Infinite Loop of React.useEffect()
February 26, 2023 - Open the fixed demo. Type some words into the input... and as soon as you enter the special word 'secret' the secrets counter increments. No infinite loop is created. That's a win! useEffect(callback, deps) is the hook that executes callback (the side-effect) after deps changes.
🌐
Stack Overflow
stackoverflow.com › questions › 67360561 › useeffect-dependency-array-causing-infinite-loop
reactjs - useEffect dependency array causing infinite loop - Stack Overflow
I'm getting the following warning in the console: Line 19:6: React Hook useEffect has a missing dependency: 'data'. Either include it or remove the dependency array and res.data is an empty array ...