The problem can be found in your onClick
prop:
<button className="previous-round" onClick={setOrderData_(previous(orderData_))}>‹</button>
^
Everything between the curly braces gets evaluated immediately. This causes the setOrderData_
function to be called in every render loop.
By wrapping the function with an arrow function, the evaluated code will result in a function that can be called whenever the user clicks on the button.
<button className="previous-round" onClick={() => setOrderData_(previous(orderData_))}
>‹</button>
You can find more information about JSX and expressions in the official docs
https://reactjs.org/docs/introducing-jsx.html#embedding-expressions-in-jsx
Infinite re-render loop
The reason for the infinite loop is because something (most likely setState
) in the event callback is triggering a re-render. This will call the event callback again and causes React to stop and throw the ‘Too many re-renders.’ error.
Technical explanation
To better understand the reason why JSX works this way see the code below. JSX is actually being compiled to Javascript and every prop will be passed to a function in an Object. With this knowledge, you will see that handleEvent()
is being called immediately in the last example.
// Simple example
// JSX: <button>click me</button>
// JS: createElement('button', { children: 'click me' })
createElement("button", { children: "click me" });
// Correct event callback
// JSX: <button onClick={handleClick}>click me</button>
// JS: createElement('button', { onClick: handleClick, children: 'click me' })
createElement("button", { onClick: handleClick, children: "click me" });
// Wrong event callback
// JSX: <button onClick={handleClick()}>click me</button>
// JS: createElement('button', { onClick: handleClick(), children: 'click me' })
createElement("button", { onClick: handleClick(), children: "click me" });