Alex Sidorenko AvatarAlex Sidorenko

15 Dec 2022

Why does onClick={x()} cause a 'too many re-renders' error in React?

Two examples with different event handlers side by side

What's the difference? Why does the second example cause an infinite loop?

Setting an event handler

First, let鈥檚 check the example that sets an event handler correctly.

Set an event handler in React

JavaScript has first-class functions. This means we can pass a function around like any other value. Here, we're 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 triggers a state update, and our component re-renders. Everything works as expected 馃憣

Causing an infinite loop

Now let's examine the example that leads to an infinite loop. But first, here's 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 onClick1. But for onClick2, we assign the result of execution x(1). This means we call x(), get its return value, and assign it to onClick2.

The same thing happens in our React example. We're trying to assign the result of executing setCount to onClick. Not only will this not work because setCount doesn't return any value, but it will also cause an infinite loop because we're updating the state during the render phase of the React component.

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

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

Here's another vanilla JavaScript example:

function render() {
render();
}

render();

Yes, this code leads to infinite recursion.

Recursion

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

Coding Challenge 馃檶

This CodeSandbox Example causes a "too many re-renders" error. Can you fix it?


Follow me on 饾晱 for short videos about Next.js

饾晱 Follow for more