DEV Community

onClick={someFunction} VS onClick={()=>someFunction}

itric on June 22, 2024

The difference between onClick={someFunction} and onClick={() => someFunction} in React (or JavaScript in general) lies in how and when they han...
Collapse
 
efpage profile image
Eckehard • Edited

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:

function f1(a){  return a*2 }  // function definition
const f2 = (a) => { return a*2 } // arrow function
const f3 = a => a*2 // short form of arrow function
Enter fullscreen mode Exit fullscreen mode

so, this is a bit misleading / wrong:

Each time the component renders, a new function is created.

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:

function f1(a){  return a*2 }  // function definition
const f2 = f1 // function reference
const f3 = a => f1(a) // function call inside an arrow function
const function f4(a){ return f1(a)}
Enter fullscreen mode Exit fullscreen mode

It is more important to know, WHERE a function is defined and what it´s actual context is.

Collapse
 
tuzebra profile image
Huy Phan

so, this is a bit misleading / wrong:

Each time the component renders, a new function is created.

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.

Collapse
 
efpage profile image
Eckehard

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

Collapse
 
hassanzohdy profile image
Hasan Zohdy

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:

const double = (value: number) => () => {
   // do whatever needed to be done
};
Enter fullscreen mode Exit fullscreen mode

And the usage will be something like:

<div onClick={double(2)} />
Enter fullscreen mode Exit fullscreen mode
Collapse
 
mithuahammad profile image
Mithu Ahammad

it's Easy...

Collapse
 
milan_vadhel profile image
Milan Vadhel

Currying function

Collapse
 
happymalyo profile image
Mario Francisco Randrianandrasana • Edited

I think the article said about the component on each render is correct :

Each time the component renders, a new function is created.

function someFunction( ) { console.log('message') };
//here, it doesn't create a new function on click event, just call it
onClick={ someFunction } 
//here, it creates an anonymous function then call someFunction  
onClick={() => someFunction() } 

Enter fullscreen mode Exit fullscreen mode
Collapse
 
itric profile image
itric • Edited

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

Collapse
 
efpage profile image
Eckehard

Your welcome!

Collapse
 
sloan profile image
Sloan the DEV Moderator

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!

Collapse
 
raghuwarjangir profile image
Raghuwar Jangir • Edited

great content 👍for beginners it's good practice.

Collapse
 
jgdevelopments profile image
Julian Gaston

Nice article. Good stuff!!

Collapse
 
syedmuhammadaliraza profile image
Syed Muhammad Ali Raza

👍

Collapse
 
efpage profile image
Eckehard

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:

// function sayHi(){
const sayHi = () =>  {
  console.log("Hi");
  sayHi.counter++;
}
sayHi.counter = 0; // initial value

sayHi(); // Hi
sayHi(); // Hi

console.log( `Called ${sayHi.counter} times` ); // Called 2 times
Enter fullscreen mode Exit fullscreen mode

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:

run2 = () => {
  let f = function (){
    console.log("Hi2")
    f.counter ++
  }
  f.counter = 0
  return f
}

let x 
x = run2(); x()
x = run2(); x()
console.log( `Called ${x.counter} times` ); // Called 1 times
Enter fullscreen mode Exit fullscreen mode

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.

Collapse
 
mekkj98 profile image
keshav jha

There is alternate way in which you can use something like data-{xyz} attribute in element and onclick or on any event, you can get that attribute value using e.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>

Collapse
 
dillonheadley profile image
Dillon Headley

If you are using data attributes you should use e.target.dataset to read them. Like e.target.dataset.message

Collapse
 
mekkj98 profile image
keshav jha • Edited

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.

Collapse
 
chavansoham profile image
Chavan-Soham

So output will be "Button clicked" because you have passed this value to data-message attribute right ?

Collapse
 
douglaspujol profile image
Douglas Pujol

Excellent article

Collapse
 
gihanrangana profile image
GihanRangana

This will be the cleanest way to pass arguments to the function

function handleClick(message) {
  console.log(message);
}

<button onClick={handleClick.bind(null,"Button Clicked")}>Click Me</button>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
shepardm7 profile image
Sateek Roy • Edited

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 the useCallback hook.

const testFn = () => { console.log('Hello'); }
console.log(testFn.bind(null) === testFn.bind(null)); // false
Enter fullscreen mode Exit fullscreen mode

Try this code in the browser console and you'll get false as the output which proves that bind will also cause a re-render.

Collapse
 
ed1nh0 profile image
Edson Jr.

Have you actually read what you wrote?
Cleaning up your sentences a bit I got:

onClick={someFunction}
The function someFunction will be called when the onClick event is triggered

onClick={() => someFunction()}
someFunction is called immediately when the onClick event is triggered.

I didn't got it to be honest.

Collapse
 
iliadtoboggan profile image
Iliad toboggan

Is this not just an AI generated response to the title?

Collapse
 
itric profile image
itric

yep, it is. Actually it is a mixture of two LLM responses, i combined it and made some appropriate adjustments. I think it was useful to share so i did.

Collapse
 
mmhgarcia profile image
Alberto G

I like your post. Good análisis. 👍👍

Collapse
 
sanjay_1212 profile image
gaming teach • Edited

Another Difference is

when use And Try This :
<button onClick={handleClick('Button clicked')}>Click Me</button>
then chrome is thro error which is :
Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

Collapse
 
vipin_tiwari_8f09b41bedbb profile image
vipin tiwari • Edited

onClick={() => someFunction()}

  • gets recreated on each render.

onClick={someFunction}

  • any normal function like 'someFunction' also gets recreated on each render in react.

So, my doubt is in what sense, the 'onClick={() => someFunction()}' is used for better optimization in comparision to 'onClick={someFunction}'?

any explanation would help..........

Collapse
 
sabbircs profile image
Sabbir Hossen

I think i waste my time :(

Collapse
 
velumurugesan profile image
velu-murugesan

In useState why I get multiple re-rendering.please answer me

Collapse
 
free_123 profile image
free_123

Firstly, exclude whether it is a development environment. In development mode, useSate may re render multiple times, but React's statement is that it should not be affected by this mechanism during development. If there is an impact, your code needs to be optimized for side effects

Collapse
 
rishabh_singh_9db8a818c94 profile image
rishabh singh

When will the use of direct function will cause problem?