Short answer
Something sets state on every render. The most common cause is onClick={handleClick()}, which calls the function during render instead of passing it. Write onClick={handleClick} or onClick={() => handleClick(id)}. If the loop runs through useEffect, the Effect sets state that changes its own dependencies: remove the Effect, depend on a primitive value instead of an object, or keep the value in a ref.
What sets state on every render, and the fix
01
A set function called directly while rendering
“Typically, this means that you're unconditionally setting state during render, so your component enters a loop” React, useState: Troubleshooting
React throws Too many re-renders when a component calls a set function in its body with no condition. Each call schedules another render, and that render calls it again. Move the update into an event handler or an Effect, or compute the value during render without storing it in state.
02
onClick={handleClick()} instead of onClick={handleClick}
“Very often, this is caused by a mistake in specifying an event handler” React, useState: Troubleshooting
The parentheses call the handler while React renders the button, and if the handler sets state, that starts the loop. Pass the function itself, or wrap it in an arrow function when it needs an argument:
// loops: calls the handler during render <button onClick={handleClick()}>Save</button> // works <button onClick={handleClick}>Save</button> <button onClick={() => handleClick(id)}>Save</button>03
An Effect that updates its own dependency
“That state leads to a re-render, which causes the Effect's dependencies to change.” React, useEffect: Troubleshooting
When the loop goes through useEffect, React’s development build usually warns Maximum update depth exceeded instead. The Effect sets state, the new state changes a value in its dependency array, so it runs again. A common version is an object or array created during render in the dependency list: it is new on every render. Depend on the primitive values inside it, move it into the Effect, or remove the Effect if it only derives data from props or state.
// loops: filters is a new object on every render const filters = { status }; useEffect(() => { setRows(applyFilters(data, filters)); }, [data, filters]); // works: no Effect, compute during render const rows = applyFilters(data, { status });04
A value that does not need to cause a render
“If you need to keep track of some data that isn't used by rendering, a ref (which doesn't trigger re-renders) might be more appropriate.” React, useEffect: Troubleshooting
Counters, timers, previous values and flags that the screen never shows do not belong in state. Keep them in useRef: changing a ref does not render the component again, so it cannot start a loop.
Checked against the vendor’s docs on : React docs: useState, “Too many re-renders”; React docs: useEffect, an Effect re-running in an infinite cycle.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
Related: Next.js hydration error · Next.js “window is not defined” · React Native “Text strings must be rendered within <Text>”