Why to pass function reference instead of method in onClick event of button in ReactJS? - reactjs

Whenever I pass function parentheses in onClick of button, it automatically calls when page loads even without clicking on button.
But when I don't pass function parentheses in onClick of button, it calls only when button is clicked.
With passing parentheses in function call
<button onClick={this.handleButtonClick()}>Increment</button>
Without passing parentheses in function call
<button onClick={this.handleButtonClick}>Increment</button>
Why function called automatically on page load whenever I pass parentheses to function even-though it is written inside onClick of button ?

There's a difference between a function call and a function.
When a component renders, all statements are executed and expressions are evaluated. It's plain javascript, that's how javascript works.
this.handleButtonClick() is a function call, and therefore the function will be called once the component renders. I assume that handleButtonClick() returns undefined which will cause the button to render as <Button onClick={undefined} />. Now, if onClick is undefined, nothing will happen when the click actually happens as there is no function to be called.
this.handleButtonClick is just a reference to a function, it doesn't invoke it. You need to pass the function reference to onClick prop so that it can be called later by React, once the click actually happens.

It automatically calls because you are invoking it immediately by:
this.handleButtonClick()
"onClick" does not work like that, if you want to manually invoke the function you can use:
onClick={() => this.handleButtonClick()}
This is done automatically if you use function reference. Hence, you don't need to invoke it or use a callback function. Actually, using function reference is better since that function isn't recreated in every render.

There is a difference between function reference and function invoking.
When you set the dynamic value like:
this.handleButtonClick()
that means you're invoking the function as soon as the component renders to the page.
But when you just pass the reference of the function like
this.handleButtonClick
that means React will call this function only when the user clicks on it.

JS will execute the function On each Render when you do OnClick(Func(params))
because you are calling a function instead of passing it.
Do this instead :
OnClick ( ()=> {Func(params) } )

In react functional components, if we pass any function to onclick this way.. onClick={func()} this func will be called right away when the page is loaded, that for sure we don't want.
So we have two ways to make it work right.
one, pass it as a reference like this- onClick={()=> func()} (this means only pass reference to that function when page loads, but call that func() if component is clicked over.)
second, just pass the name of the function- onClick={func} (this means both pass reference and call on Call).
these both things work the same way. second one is more easy however the former one is used the most.

Related

Difference between onClick={function()} and onClick={()=>function()} in React

when trying to call this function onClick,
function changeProfile(e){setProfilePic(e)}
when I use
onClick={changeProfile(props)}, it calls the function whenever the page is loaded, and doesn't work properly as it calls all the props at once even the ones that are not called.
onClick={()=>{changeProfile(props) this works exactly how I imagined, calling only the component that is clicked. What is the difference between the two and when do I use the specific method of {()=>function}??
I know that it works now, but what is the exact difference between the two?
onClick={()=>{changeProfile(props) will register an event handler to the click event.
onClick={changeProfile(props)} will run when it is encountered in the code. This is why it occurs on the page load.

How are function calls and component calls different in React?

https://codesandbox.io/s/cocky-silence-486sh?file=/src/App.js
In the above example, we see that calling the ChildWrapper as ChildWrapper() vs <ChildWrapper/> causes some differences.
The function method behaves as intended, so when I increment the counter, the reference stays the same, however using the component call, it actually remounts.
I was wondering if my intuition is correct, that the references are changing, and more important why are they changing. And to add on to that, which should be the preferred method for rendering functions that returns jsx, <Component/> or { Component() }.
When you do <ChildWrapper/> it is translated to React.createElement(ChildWrapper, {}, null) which means you ask react to create an element for you.
When you do ChildWrapper() you are just calling a function, react does not know about this and cannot know about it, so you won't have any of react's features (hooks).
With your example, with logging the two results in the console you will see this, and you can notice that the difference is noticeable:
When calling the function, it will return a <div>, here, jsx will transpiles it to an object with type div.
When calling it via jsx from the start, it will return an object with type ChildWrapper.
PS: you are creating the ChildWrapper inside a component (during render) So it will have a new value each time your Parent component renders, and react after rendering and going into reconcialiation, it will remove the whole previous tree and create a new one, because the type changed.
Let's sum up all what I've wrote:
The child "behaving correctly for you" is the function call, because you basically call it and it returns a div, react after render and during reconciliation, finds a div and then just updates it if there is a change. So the mount useEffect(() => ..., []) will not be executed.
Why the child created with jsx isn't behaving correclty ? because you are dynamically creating its type, so at each render, it will create a new ChildWrapper Type, and react during reconciliation will remove it entirely because its type changed, and thus, the mount useEffect(() => ..., []) will be executed each time, because every time we mount a new element.
Read more about reconciliation in this link
From the official documentation :
Each JSX element is just syntactic sugar for calling
React.createElement(component, props, ...children). So, anything you
can do with JSX can also be done with just plain JavaScript.
Internally, the code generated looks like this: React.createElement(Component, { props }, children),
The createElement function will then register and render the component you gave to it, bind it with the shadow DOM and update it whenever it is necessary. It will also pass its props and children arguments.
But if you call your component directly, none of that happens, your component will not be correctly rendered and updated by react because it lacks the core features given by createElement.

Why are functions invoked from event handlers considered "callback" functions? (React)

I am trying to wrap my head around the idea that a function called from an event handler like onClick is considered a callback function?
For example if I have "onChange={this.handleChange}" which calls a class function called handleChange(), why is handleChange a callback here? My understanding is that a callback is a function that is passed into ANOTHER function as a parameter? Am I missing something? Thank you.
this.handleChange does indeed get passed as an argument to a function, just not in your code. React takes care of calling domElement.addEventListener('click', this.handleChange) for you.
"Callback" is also a generic term for a function that is called when a given event occurs. Often these functions are passed in as parameters to other functions, because they allow the function being called to "notify" the caller when something happens. In this case, the event is the click, and the callback is the function executed when the click occurs.
My understanding is that a callback is a function that is passed into ANOTHER function as a parameter?
That is exactly correct. More generally it is a function that you pass to some other piece of code that will "call back" to your function when something happens.
A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action
The above is from MDN web docs.
Since the function is being called in response to an event being detected, it is passed as an argument to event handler. An event handler is a function called when an event (click) happens.

Why sometimes I see an arrow function and other just the the function on event handlers in react?

Sometimes I see this on a react handler:
<Results onClick={() => this.somefunction()}/>
and other times like:
<Results onChange={this.handleChange} />
What is the mail difference on these ways of writing the code?
In your first example somefunction doesn't need to worry about having access to the wrong this: it will refer to the instance of the class that's defined in.
Your second example may not have the same certainly, depending on how's defined: you will need to bind the function or use arrow functions.
The actual react documentation provide more insight on this: https://reactjs.org/docs/handling-events.html
Also: referential identity. The first example create a new function on every render. It may mess up with pure component, because the props will keep changing. The second example pass always the same function: pure component will see them as the same props as before and won't re-render unnecessary.
The former 'hoists' the someFunction in a callback to be ran at a later time. The latter looks for the code in handleChange immediately.
Also, you have the context issue with this. In an arrow function, this doesn't attach context to the function itself, but rather to the parent context. In essence, this would have the same context in each of these examples.

React onChange function. Nothing is getting passed like event?

I am doing a react tutorial and I see this code:
So I guess we need to just supply a function to the onChange field... not actually call it. That's why we don't need to pass event to the function when it itself is being passed to onChange right? What is onChange called btw? Does it have a name in react?
I guess whatever function we pass to onChange, React attempts to pass the event to it right?
Yes. Basically React creates its own SyntheticEvent wrapper over original event (it has almost the same API as original one) and passes it to your event handler as first argument. Also you are correct about passing a function without calling it, React will call it for you on event.

Resources