K.Kaur
K.Kaur

Reputation: 91

Calling Method in different way in React

// 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

Answers (3)

ash1102
ash1102

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

jyjin
jyjin

Reputation: 103

Those 4 types calling way cause react doesn't bind this for react event.

1.bind this in constructior(suggest)

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}

2.bind this on event callback

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)}

3.bind this by es6 arrow function

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}

4.bind this directly (bad)

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

Axnyff
Axnyff

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

Related Questions