This happens because when you pass onClick={setState(1)}
the actual value that will be used as the onClick
callback function is the return of the call of setState(1)
. As this call results in a side-effect (state change), the component will be re-rendered and it'll be an infinite loop.
Why this happens?
The onClick
prop receives a callback function. If you want that function to be called when the user clicks you should pass it like this:
<button
onClick={() => setState(1)}
//or
onClick={setState}
>Click me!</button>
But if you use the second option, it'll receive the event
(a SyntheticEvent
type) and pass it to the setState()
function. It'll be something like this:
<button onClick={(event) => setState(event)}>Click me!</button>
This happens because JSX is "transpiled" by React by converting all the props to key-value
pairs and passing them to a function call(read more here about it). Consider the options:
<button
// option 1:
onClick={setState}
// option 2:
onClick={() => setState(1)}
// option 3:
onClick={() => {
setState(1);
}}
// option 4:
onClick={setState(1)}
>Click me!</button>
They'll be converted to something like this (roughly):
react.createElement(
"button",
{
// option 1:
onClick: setState,
// option 2:
onClick: () => setState(1),
// option 3:
onClick: () => {
setState(1);
},
// option 4:
onClick: setState(1),
children: "Click me!"
}
)
- Option 1 will directly pass the function itself
- Option 2 will pass the callback that triggers the
setState()
call and returns its result to the caller
- Option 3 will pass the
setState()
but returns to the caller null
, as nothing is returned from that
- And finally, option 4 (your case) will pass to the callback the return of the
setState()
call and use that as a callback.
Why do I want this?
Eventually, you want to return a function from a function call. There are several uses for that but one simple one is creating a function based on some parameters such as:
const add = (to) => (value) => to + value;
const addTwo = add(2);
console.log(addTwo(3));