Reputation: 91
// can anyone help me get an output and behaviour of this particular code block and what's the difference between binding function in all these forms
class App extends React.Component {
constructor() {
super();
this.name = 'MyComponent';
this.handleClick2 = this.handleClick1.bind(this);
}
handleClick1() {
alert(this.name);
}
handleClick3 = () => alert(this.name);
render() {
return (
<div>
<button onClick={this.handleClick1()}>click 1</button>
<button onClick={this.handleClick1}>click 2</button>
<button onClick={this.handleClick2}>click 3</button>
<button onClick={this.handleClick3}>click 4</button>
</div>
);
}
}
Upvotes: 0
Views: 64
Reputation: 457
without any arguments, you can just pass the reference of the function in your callback
<button onClick={this.handleClick1}>click 1</button>
with arguments, you still pass the reference but by providing the whole function inside another function probably with the arrow syntax like this.
<button onClick={() => {this.handleClick1(arg1,arg2...)}}>click 1</button>
we bind the function inside constructor because that is where this
means the instance of your class.
if you don't do it and use this
inside a function react interprets that as the window object and not the instance of the class that is why many times you may get undefined.
if you don't wish to use binding of this
in the constructor just change your handleClick1 to an arrow function. Then you can use both button format as shown above.
Upvotes: 1
Reputation: 103
Those 4 types calling way cause react doesn't bind this
for react event.
It's a highest efficiency way to bind this, cause react create its own event system in a queue, all event are delegate to document and do batch option when event fires. And this way it will be bind this before rendering in lifecycle, so it is high efficiency.
Usage
constructor(){
this.onClick1 = this.onClick1.bind(this)
}
<button onClick={this.onClick1}
This way bind your event when react rendering which means bind when calculating virtual DOM in lifecycle
Usage:
onClick2(){
...
}
<button onClick={()=>this.onClick1.bind(this)}
Also you can bind this by es6 arrow hooks, this way bind this cause babel transfer your code es5 when your project has released.
onClick3 = () => {
...
}
<button onClick={this.onClick3}
This way will running when you page loading, and can't get this.
constructor(){
...
this.state = {
foo: 'bar'
}
}
onClick4(){
alert(this.state) // throw exception cause can't recognize this
}
<button onClick={this.onClick4}
Upvotes: 1
Reputation: 9944
<button onClick={this.handleClick1()}>click 1</button>
This is wrong: onClick's event handler will be the result of the call to this.handleClick1
with returns undefined.
What you meant is probably
<button onClick={() => this.handleClick1()}>click 1</button>
In this case, as you're using an arrow function it won't override the value of this
and thus work as expected.
<button onClick={this.handleClick1}>click 2</button>
This won't work as expected, this
will be undefined inside of your function as the function won't be called as a method.
<button onClick={this.handleClick2}>click 3</button>
In this example, we are creating a function for which this
is bound so it will work property.
<button onClick={this.handleClick3}>click 4</button>
This fourth function is defined as an arrow function attribute so this won't be dependent on the way to call it and will work as expected.
Personally, I'd prefer using the fourth method as there's no extra boilerplate, and there's no potential overhead, contrary to defining an inline arrow function as in method 1
Upvotes: 1