Alex Sidorenko

Why does onClick={x()} causes "too many re-renders" error in React?

December 15, 2022

Two examples with different evnet handlers side by side

What is the difference? Why does the second example cause the infinite loop?

Setting event handler

First, let’s check the example that sets an event handler correctly.

Set an event handler in React

Javascript has First class functions. This means that we can pass a function around like any other value. Here we are passing an arrow function () => setCount(count + 1) to the onClick prop of React. When a user clicks the button, React will call this function. This will trigger a state update, and our component will re-render. Everything is 👌

Causing an infinite loop

Now let’s check the example that leads to an infinite loop. But first, here is some vanilla Javascript code.

const x = n => n

const onClick1 = () => x(1)
const onClick2 = x(1)

console.log(onClick1) // () => x(1)
console.log(onClick2) // 1

In this code, we assign an arrow function () => x(1) to the onClick1. But to the onClick2, we assign the result of the x execution. It means that we call x(), get its return value, and assign it to onClick2.

The same happens in our React example. We are trying to assign a result of setCount execution to onClick. Not only this won’t work because setCount doesn’t return any value, but it will also cause an infinite loop because we update the state during the render phase of React component.

Cause an infinite loop by calling setState instead of passing a funcion as an event handler

Why does updating the state during the rendering cause an infinite loop?

Another vanilla Javascript example.

function render() {
  render()
}

render()

Yep, this code leads to infinite recursion.

Recursion

The same happens with React when we try to update a state during the render phase.

Coding Challenge 🙌

This CodeSandbox Example causes “too many re-renders” error. Could you fix it?