FactorialTime
FactorialTime

Reputation: 147

Why do I have to wrap the functions of my onClick attributes in anonymous functions in React?

Sorry for the confusing title; if I have an onClick attribute on one of my components such as the following

<Component onClick={this.doSomething()} />

I will often get weird errors depending on what the doSomething() function is actually calling. If doSomething() is changing state particularly I get all sorts of render errors. On the other hand if I do this

var _this = this;
<Component onClick{
   function(){
      _this.doSomething()
   }
} />

All the errors go away and everything works as I intended. What exactly am I doing by wrapping my onClick attribute in an anonymous function that makes this work? Is there a better way of doing what I am trying to do?

Upvotes: 1

Views: 1524

Answers (1)

Tom Fenech
Tom Fenech

Reputation: 74685

If you do this:

<Component onClick={this.doSomething()} />

Then you're calling the function and assigning the return value to the onClick attribute. If this.doSomething() modifies the component state during a render, then this will cause problems.

You should be able to use:

<Component onClick={this.doSomething} /> 

i.e. remove the (), so the function is assigned to the attribute, rather than the result of executing the function.

In the constructor of your component class, you should include the following line:

this.doSomething = this.doSomething.bind(this);

You can use onClick={this.doSomething.bind(this)} too but this means that a new function is created every time the component is re-rendered.

The binding behaviour of this within a component class varies, depending on how the component is created:

  • Using the class keyword (ES6), this is not automatically bound
  • Using React.createClass, this is bound

With ES7, you also have a couple more options:

  • Using doSomething = () => { //... instead of the function keyword
  • Using onClick={::this.doSomething}, a shorthand way to bind this

Thanks to Zequez for their useful comment.

Upvotes: 10

Related Questions