React onClick Explained: Function calls vs Function Reference
When I first started working with React, one of the things that confused me was handling the onClick event. I often found myself mixing up onClick={() => myFunction()} and onClick={myFunction()}, not realizing why one worked and the other caused unexpected behavior.
After making this mistake several times, I decided to dig deeper into how React interprets function calls vs. function references in event handlers. In this article I will share some of the practical examples where each approach works (or doesn’t work).
This article is an improvised version of my previous article written around the similar topic. Thanks for the precious feedback from @Sena.brauch, @kristofajosh and @patricknelson to extent this topic further
Link to the previous article:https://medium.com/@QA-initi/react-the-different-between-these-two-codes-syntax-onclick-removeitem-id-and-aa9ee07a56c8
Understanding the Difference Between onClick={() => removeItem(id)} and onClick={removeItem(id)} in React
When working with event handlers in React, a common source of confusion is the difference between writing:
onClick={() => removeItem(id)}and
onClick={removeItem(id)}At first glance, both look similar — but they behave very differently. Let’s break it down with examples.
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
1. Using onClick={() => removeItem(id)} (✅Correct Approach)
Here, an arrow function is created for the onClick handler. This means:
- The function
removeItem(id)is not called immediately. - Instead, React stores the arrow function and executes it only when the button is clicked.
- This is the recommended approach when we need to pass arguments to the function.
Example:
<button onClick={() => removeItem(id)}>Remove Item</button>➡️The removeItem function will only run after the user clicks the button
2. Using onClick={removeItem(id)} (❌ Usually Incorrect)
Here, we are directly invoking the function removeItem(id) while React is rendering the component. This means:
removeItem(id)runs immediately during render.- Whatever the function returns gets assigned to
onClick. - If it doesn’t return a function, React won’t have a valid event handler — causing errors or unexpected behavior.
Example:
<button onClick={removeItem(id)}>Remove Item</button>➡️ This will call removeItem(id) immediately, not when the button is clicked.
3. When Can You Use a Direct Method Call Without Errors?
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
Get QA-init’s stories in your inbox
Join Medium for free to get updates from this writer.
There are some valid scenarios where we can safely write onClick={someFunction} without using an arrow function.
➡️ Scenario A: Function with No Arguments
If the function doesn’t need parameters, we can pass it directly as a reference.
function handleClick() {
alert("Button clicked!");
}
<button onClick={handleClick}>Click Me</button>- Works perfectly because React stores the reference to
handleClickand only calls it when the button is clicked. - If we write
onClick={handleClick()}, it would execute immediately during render. Notice the brackets immediately following the handleClick which is not correct.❌
➡️Scenario B: Function That Returns Another Function
If the function returns a new function (a “curried function”), calling it directly is fine.
function createHandler(id) {
return () => {
alert("Item ID: " + id);
};
}
<button onClick={createHandler(5)}>Show ID</button>- Here,
createHandler(5)runs during render but returns a function. - That returned function is then assigned to
onClick, so React has a valid event handler.
️ ️➡️Scenario C: Direct Function Reference (No Extra Wrapping)
If no arguments are needed, we don’t need the arrow function wrapper at all.
function sayHello() {
console.log("Hello!");
}
<button onClick={sayHello}>Say Hello</button>- React only calls
sayHellowhen the button is clicked. - This is the simplest and most efficient way when no parameters are required.
➡️Scenario C: Built-in JavaScript function
We can also directly use built-in functions, though React will pass the event object as an argument.
<button onClick={console.log}>Log Event</button>- Clicking the button will log the click event object.
- This works because
console.logis a valid function reference.
🟩In Summary:
- Use
onClick={functionName}→ when the function takes no arguments. - Use
onClick={() => functionName(arg)}→ when we need to pass arguments. - Avoid
onClick={functionName(arg)}unless the function returns another function.
🟩Example:
onClick={() => removeItem(id)}→ safe, common, and correct way when passing arguments.onClick={removeItem(id)}→ runs immediately and usually causes issues, unless the function returns another function.- Passing a function reference directly (
onClick={sayHello}) is fine when no arguments are needed.
That’s all for today. Happy reading!!!!








