This question already has an answer here:
React: onClick handler is getting called on every render?
(1 answer)
Closed 5 years ago.
I understand that this is not the right way to make a button show an alert on click.
I would like to understart the logic behind this.
I understand that on click needs to get a reference to a function in order to function as expected.
In the following example, a reference is being made to an arrow function which will be called on click:
<button onClick={() => alert('hi)}>Click me!</button>
But what happens behind the scenes in this case:
<button onClick={alert('hi)}>Click me!</button>
Why is the statement inside onClick being evaluated at render?
Edit: I am using React.
Imagine you have a method like so:
function getString(){
return "string";
}
and then define a textbox:
<input type="text" value={getString()}/>
You would expect that the textbox would be rendered with a value of "string" not "getString()". This is because what is within the curly braces is evaluated in the render method.
When {alert('hi)} is evaluated it runs the method so what is assigned to the onclick event is what is returned by alert('hi') (nothing) not the method itself.
In react application, we write html in javascript and not in HTML.
So at the time of rendering, javascript will execute this function: alert('hi')
By using this syntax:
<button onClick={() => alert('hi')}>Click me!</button>
we are passing function reference to on click. Inner block of this function will only be executed when this event is called.
Related
This question already has answers here:
addEventListener calls the function without me even asking it to
(5 answers)
Closed 4 years ago.
I'm trying to create some appropriately-placed instructional tooltips that users click through to understand how the site interface works. Each tooltip has a "next" link that toggles the visibility of the previous and next tooltips by modifying the classes (and hence, css).
Here's some simplified code that is supposed to do this:
function displayTooltip(t){
//...some code to determine the tooltip IDs "next" and "previous"
document.getElementById(previous).className = "tooltip invisibleTooltip";
document.getElementById(next).className = "tooltip";
}
document.getElementById("tooltip-link1").addEventListener("click", displayTooltip(2));
displayTooltip is called immediately (and correctly toggles the class) when I paste this code into the console (or on page load). If I replace displayTooltip with an alert(), it fires when I click, as anticipated. What am I doing wrong?
When you are binding event you are calling the function document.getElementById("tooltip-link1").addEventListener("click",displayTooltip(2));
You need to pass reference to the function.
Change to below
document.getElementById("tooltip-link1").addEventListener("click", function(){
displayTooltip(2)
});
When you write functionName followed by (), it will call function. If you wish to assign function to a handler, you should do
document.getElementById("tooltip-link1").addEventListener("click", displayTooltip);
Now if you wish to pass parameter to this function, you can either wrap it inside a function like
document.getElementById("tooltip-link1")
.addEventListener("click", function(){displayTooltip(2)});
Or you can use .bind()
document.getElementById("tooltip-link1")
.addEventListener("click", displayTooltip.bind(this, 2));
You need to call this method as a callback. Since you are calling it as displayTooltip(2) you are ultimately calling the function at that line.
What you need to do is to bind a callback rather than calling at that line.
Something like
.addEventListener('event', function()
{ displayTooltip(2) }
Hope this be of some help
Happy Learning
This question already has answers here:
What is the logic behind the arrow function behaves differently when taking values?
(8 answers)
Difference between using Arrow function or function for onClick in ReactJS?
(2 answers)
Question: Call the function and passing in an anonymous arrow function that alerts the spliced value
(2 answers)
Closed 5 months ago.
I've seen in many place those two options to do the things but don't know which is the difference more exactly between this:
<Button onClick={doSomething} title='OK' />
and this:
<Button onClick={() => doSomething()} title='OK' />
<Button onClick={doSomething} title='OK' />
You pass the function reference to the onClick event to execute, on my opinion mostly I use it
When I just want to execute one function on the click event.
When I don't need any parameters or just the event parameter.
<Button onClick={() => doSomething()} title='OK' />
you execute the function inside the outer callback, which I usually do when I want to
Execute more than one function on the click.
When I need to pass more parameters to the function than the event parameter.
Some Notes
Just note you can just pass the function reference and use bind() to pass more parameters than the event parameter.
For performance optimization, If you use memo hook with the child component it would be better to use useCallback hook with the function
There is very little difference, in all honesty. The named function option allows you to centrally maintain the logic but prevents you from using it directly in various places where the handler signature may vary.
The arrow function form, on the other hand, allows you to "proxy" disparate event function signatures into your own function. This is something like the Adapter pattern, where you "translate" something (the specific event parameters) into something else (your specific function's parameters).
In short, the arrow function will allow you more flexibility in the long run, but both are the same thing, in essence: Objects of type function.
Furthermore, arrow functions cannot get their this variable redefined. If you ever find yourself in need of this, go for the arrow function variant.
When using this:
<Button onClick={doSomething} title='OK' />
You can't pass parameter to the function.
<Button onClick={() => doSomething()} title='OK' />
With this one you can pass a parameter for example
As #deceze said in the comments: this will receive any argument that you passed from outside not an argument that onClick will pass
<Button onClick={() => doSomething(row.id)} title='OK' />
This question already has answers here:
addEventListener calls the function without me even asking it to
(5 answers)
Closed 4 years ago.
I'm trying to create some appropriately-placed instructional tooltips that users click through to understand how the site interface works. Each tooltip has a "next" link that toggles the visibility of the previous and next tooltips by modifying the classes (and hence, css).
Here's some simplified code that is supposed to do this:
function displayTooltip(t){
//...some code to determine the tooltip IDs "next" and "previous"
document.getElementById(previous).className = "tooltip invisibleTooltip";
document.getElementById(next).className = "tooltip";
}
document.getElementById("tooltip-link1").addEventListener("click", displayTooltip(2));
displayTooltip is called immediately (and correctly toggles the class) when I paste this code into the console (or on page load). If I replace displayTooltip with an alert(), it fires when I click, as anticipated. What am I doing wrong?
When you are binding event you are calling the function document.getElementById("tooltip-link1").addEventListener("click",displayTooltip(2));
You need to pass reference to the function.
Change to below
document.getElementById("tooltip-link1").addEventListener("click", function(){
displayTooltip(2)
});
When you write functionName followed by (), it will call function. If you wish to assign function to a handler, you should do
document.getElementById("tooltip-link1").addEventListener("click", displayTooltip);
Now if you wish to pass parameter to this function, you can either wrap it inside a function like
document.getElementById("tooltip-link1")
.addEventListener("click", function(){displayTooltip(2)});
Or you can use .bind()
document.getElementById("tooltip-link1")
.addEventListener("click", displayTooltip.bind(this, 2));
You need to call this method as a callback. Since you are calling it as displayTooltip(2) you are ultimately calling the function at that line.
What you need to do is to bind a callback rather than calling at that line.
Something like
.addEventListener('event', function()
{ displayTooltip(2) }
Hope this be of some help
Happy Learning
Everytime I enter a character in my input textfield, it automatically presses the submit button attached to it.
I would like to enter all the characters in the input textfield before it submits.
It's this part that is causing a problem:
<input type="text" ref={this.input} onChange={this.handleChange} />
<input type="submit" className="text-success col-offset-3" onClick={console.log("clicked")} value="Add Stock"/>
For example, it will console.log "clicked" everytime I enter a character in the input textfield without me actually clicking the button
Does any one of you guys know why?
Your passing in console.log() so every time the page re-renders the function gets called. As your calling it by passing it in like that.
You need to pass it in like this:
onClick={() => console.log("Clicked")}
<input type="submit" className="text-success col-offset-3" onClick={console.log("clicked")} value="Add Stock"/>
This is calling the console.log function every time the component is rendered. It's probably why you think the form is being submitted every time you type something. You should do something like this:
<input type="submit" className="text-success col-offset-3" onClick={() => console.log("clicked")} value="Add Stock"/>
You can find some more information in the React docs: Handling Events.
Explanation:
The reason why you do this, is that in React you don't include the parenthesis on your events. So in html you would do:
Regular HTML:
<button onclick="myFunc()">Button</button>
But in React you need to do:
JSX:
<button onClick={myFunc}>Button</button>
(Note that in class components you may need to use this.myFunc).
If you use the parenthesis in React, you're actually just calling the myFunc function when that piece of code is run:
This is wrong:
<button onClick={myFunc()}>Button</button>
Now, what happens if the function needs to take some parameters? i.e. what you need myFunc to be called with some number like 123 for example? This is covered in the docs (see Passing Arguments to Event Handlers
), there are two or three ways to go about this:
Create an auxiliary function that calls the function you want to call:
Kind of messy, but I'm including this since it's a valid alternative:
// Somewhere else in your component...
myAuxFunc = () => {
myFunc(123)
}
// Inside your render...
<button onClick={this.myAuxFunc}>Button</button>
Use an arrow function:
This is somewhat similar to creating an auxiliary function. Actually we are doing the same thing, we are creating a function that calls the function we're actually interested in, only that we're not naming it (it's an anonymous arrow function) and we're creating it on the spot:
<button onClick={() => myFunc(123)}>Button</button>
This can be tricky, but it is essentially the same as the first alternative I mentioned. I'm telling react that when the button is clicked, I want the following function to be called: () => myFunc(123). It's a function that takes no parameters, and when it is called, it will call myFunc(123).
(Class components) Use the bind function to bind the this keyword:
This is useful in class components when you want to call functions defined in your components so I'm including this here for completeness. It's not actually useful when you want to call a function like console.log.
<button onClick={this.myFunc.bind(this, 123)}>Button</button>
This question already has answers here:
addEventListener calls the function without me even asking it to
(5 answers)
Closed 4 years ago.
I'm trying to create some appropriately-placed instructional tooltips that users click through to understand how the site interface works. Each tooltip has a "next" link that toggles the visibility of the previous and next tooltips by modifying the classes (and hence, css).
Here's some simplified code that is supposed to do this:
function displayTooltip(t){
//...some code to determine the tooltip IDs "next" and "previous"
document.getElementById(previous).className = "tooltip invisibleTooltip";
document.getElementById(next).className = "tooltip";
}
document.getElementById("tooltip-link1").addEventListener("click", displayTooltip(2));
displayTooltip is called immediately (and correctly toggles the class) when I paste this code into the console (or on page load). If I replace displayTooltip with an alert(), it fires when I click, as anticipated. What am I doing wrong?
When you are binding event you are calling the function document.getElementById("tooltip-link1").addEventListener("click",displayTooltip(2));
You need to pass reference to the function.
Change to below
document.getElementById("tooltip-link1").addEventListener("click", function(){
displayTooltip(2)
});
When you write functionName followed by (), it will call function. If you wish to assign function to a handler, you should do
document.getElementById("tooltip-link1").addEventListener("click", displayTooltip);
Now if you wish to pass parameter to this function, you can either wrap it inside a function like
document.getElementById("tooltip-link1")
.addEventListener("click", function(){displayTooltip(2)});
Or you can use .bind()
document.getElementById("tooltip-link1")
.addEventListener("click", displayTooltip.bind(this, 2));
You need to call this method as a callback. Since you are calling it as displayTooltip(2) you are ultimately calling the function at that line.
What you need to do is to bind a callback rather than calling at that line.
Something like
.addEventListener('event', function()
{ displayTooltip(2) }
Hope this be of some help
Happy Learning