The difference between onClick={someFunction}
and onClick={() => someFunction}
in React (or JavaScript in general) lies in how and when they handle the execution of the someFunction
when the click event occurs :
onClick={someFunction}
-
Direct Reference: This syntax directly references the function
someFunction
. -
When Clicked: The function
someFunction
will be called when theonClick
event is triggered (e.g., when the element is clicked). - No Extra Function Call: No additional function is created; React simply uses the function reference you provided.
-
Example: If
someFunction
is defined asfunction someFunction() { console.log('clicked'); }
, thenonClick={someFunction}
will log 'clicked' when the element is clicked.
onClick={() => someFunction()}
-
Arrow Function: This syntax uses an arrow function to call
someFunction
. -
Creates a New Function: Each time the component renders, a new function is created. The arrow function wraps the call to
someFunction
. -
Immediate Invocation: Within the arrow function,
someFunction
is called immediately when theonClick
event is triggered. -
Use Case: Useful when you need to pass arguments to the function or need to do additional work before calling
someFunction
. -
Example: If you want to pass an argument to
someFunction
, you can useonClick={() => someFunction('argument')}
. This will callsomeFunction
with 'argument' when the element is clicked.
When to Use Each
-
Direct Reference (
onClick={someFunction}
):- Use this when you want to avoid creating an extra function on each render, which can be more efficient.
- Preferable for simple event handlers where no additional arguments or operations are needed.
-
Arrow Function (
onClick={() => someFunction()}
):- Use this when you need to pass arguments to the function or perform additional operations before calling the function.
- Useful for inline operations or when dealing with closures.
Practical Examples
Direct Reference
function handleClick() {
console.log('Button clicked');
}
<button onClick={handleClick}>Click Me</button>
-
handleClick
will be called directly when the button is clicked.
Arrow Function
function handleClick(message) {
console.log(message);
}
<button onClick={() => handleClick('Button clicked')}>Click Me</button>
- The arrow function calls
handleClick
with the argument 'Button clicked' when the button is clicked.
Understanding these differences helps in optimizing performance and achieving the desired behavior in React components.
Top comments (31)
I don´t think this is actually correct.
A function is just just block of code between curly brackets, regardless if its defined with the function keyword or as an arrow function:
so, this is a bit misleading / wrong:
what varies is the execution context, not the function itself. It may sound a bit petty, but may lead to serious errors. It is important to get these differences exactly, as Javascript has some strange behavoir in this point (See here)[dev.to/brythewiseguy/context-in-ja...].
If you are using only pure functions, this should not matter too much unless you use the "this" keyword (which in my eyes makes the function impure)
So, calling one of this functions is pretty much the same, and might not make any measurable difference in a well optimizes Javascript compiler:
It is more important to know, WHERE a function is defined and what it´s actual context is.
In the context of this article (React using JSX syntax), what the author said is correct. But to be more clear: Each time the component renders, a new anonymous function is created to pass to the onClick props.
Actually, using arrow function syntax here is not good because of the above reason, every time the parent renders, it passes a new prop value to the child, which leads the child to do the unnecessary rerender.
Maybe you can add some more details/references. Things are complicated here so its possible I´m wrong. I think it´s important if and when a new function object is created. See here
If the function receives a parameter like
a
we can use the same concept but with HOF (Higher Order Function) to be set like this:And the usage will be something like:
it's Easy...
Currying function
I think the article said about the component on each render is correct :
i can't say, i fully understand you. i'm not an expert. i find it useful to share this info. Sorry for any misleading information, i'll be careful from next time. Thank you for correction
Your welcome!
Hey, this article appears to have been generated with the assistance of ChatGPT or possibly some other AI tool.
We allow our community members to use AI assistance when writing articles as long as they abide by our guidelines. Please review the guidelines and edit your post to add a disclaimer.
Failure to follow these guidelines could result in DEV admin lowering the score of your post, making it less visible to the rest of the community. Or, if upon review we find this post to be particularly harmful, we may decide to unpublish it completely.
We hope you understand and take care to follow our guidelines going forward!
great content 👍for beginners it's good practice.
Nice article. Good stuff!!
👍
I did some research to get more clarity on this topic. See this page for more details.
Javascript functions are just objects, so they can be extended. We can add a new property to see what´s going on. Here we add a counter to a function. Each time, the function is called, the counter is increased:
So, we can clearly see, the function only exists once and is called twice. This works with regular functions and with arrow functions in the same way.
Things are a bit different if we create the complete function body inside the an arrow function like this:
Here, each time run2 is called, we create a new function. But this happens only, if we create the whole function body inside the arrow function. It should not happen if we create the function outside and just use a reference.
There is alternate way in which you can use something like
data-{xyz}
attribute in element andonclick
or on any event, you can get that attribute value usinge.target.getAttribute("data-{xyz}")
.function handleClick(e) {
const message = e.target.getAttribute("data-message")
console.log(message);
}
<button data-message="Button clicked" onClick={handleClick}>Click Me</button>
If you are using data attributes you should use e.target.dataset to read them. Like e.target.dataset.message
Yup, performance difference is negligible but .getAttribute is faster than dataset field some extent. That is not an excuse, the thing is i got used to .getAttribute and primarily i want to fetch only couple of data attributes in most of the scenario so i'm using .getAttribute mostly.
So output will be "Button clicked" because you have passed this value to
data-message
attribute right ?Excellent article
This will be the cleanest way to pass arguments to the function
How? The
.bind
creates a new function every time the component is re-rendered. If we want to pass an argument to this function then the only way to prevent a new function from being created on a render is to create a memoized reference to that function using theuseCallback
hook.Try this code in the browser console and you'll get
false
as the output which proves thatbind
will also cause a re-render.Have you actually read what you wrote?
Cleaning up your sentences a bit I got:
onClick={someFunction}
The function
someFunction
will be called when theonClick
event is triggeredonClick={() => someFunction()}
someFunction
is called immediately when theonClick
event is triggered.I didn't got it to be honest.