In the javascript language, the behavior of the this keyword has plagued generations of junior developers. At the same time, this also fully reflects the weirdness and flexibility of javascript.

But don’t get me wrong, this article doesn’t give a full description of the characteristics of this, as these can be found in various front-end books. Here, I’ll try to talk about the evolution of the React event handler’s this binding, as well as how the javascript language has evolved in this detail. React: ES Next: React: ES Next: ES Next: React: ES Next

React has handled this context for at least five years. During the five years, a large number of proposals have emerged, so let’s summarize them first.

Method 1: React. CreateClass automatically binds

There are many ways to create components in React. Some of the older ones, such as React. CreateClass, are familiar. Of course, starting with React 0.13, it’s possible to use ES6 classes instead of React. CreateClass, which should be recommended in the future. However, it is important to know that a component created by React. CreateClass can automatically bind this. That is, the this keyword is automatically bound to the component instance.

// This magically works with React.createClass
// because `this` is bound for you.
onChange = {this.handleChange}Copy the code

Unfortunately, for component creation, the official recommendation is to use a class declared component or use a functional stateless component:

Later, classes were added to the language as part of ES2015, so we added the ability to create React components using JavaScript classes. Along with functional components, JavaScript classes are now the preferred way to create components in React.

For your existing createClass components, we recommend that you migrate them to JavaScript classes.

In my opinion, this is actually the self-improvement and future catering of the React framework itself, which is the general trend of framework and language development.


Method two: Bind at render time

From the previous section, we know that the most traditional way of creating components doesn’t have the this binding. Next, we assume that all components are declared as ES6 classes. In this case, this cannot be bound automatically. A common solution is:

onChange = {this.handleChange.bind(this)}Copy the code

This approach is succinct, but there is a potential performance problem: every time a component is re-rendered, a new function is created. OMG! This may sound like a big problem, but in real development scenarios, the performance issues that arise from this tend to be trivial (except in the case of large component consumer applications or games).


Method 3: Arrow function binding

This is similar to the second method, thanks to the ES6 arrow function, we can implicitly bind this:

onChange = {e => this.handleChange(e)}Copy the code

Of course, as with the second approach, it also has potential performance problems. Read on for two ways to avoid unnecessary performance costs.


Method 4: Bind from Constructor

The constructor method is the default method of the class and is automatically called when an object instance is generated using the new command.

So we can:

constructor(props) {
      super(props);
      this.handleChange = this.handleChange.bind(this);
}Copy the code

This approach is often recommended as a “best practice” and is my most common approach.

Personally, however, I find that the constructor bind may be a little less readable and maintainable than the first two methods. At the same time, we know that methods declared by constructor do not exist on the prototype of the instance, but belong to the methods of the instance itself. Each instance has the same handleChange, which is itself repetitive and wasteful.

If you’ve always had an open mind about ES Next and can use the features of Stage-2, try this last option.


Method 5: Use the = and arrow functions in the Class attribute

This method relies on the new features of ES Next, see TC 39: Public Class Fields

handleChange = () => {
      // call this function from render 
      // and this.whatever in here works fine.
};Copy the code

Let’s summarize the advantages of this approach:

  • This is effectively bound using the arrow function;
  • There are no potential performance problems with the second and third methods;
  • The problem of component instance duplication in method 4 is avoided.
  • We can refactor this directly from the ES5 createClass.


conclusion

In this article, we compare the five methods of binding this with React, and also take a look at the development of javascript language from ES5 bind, ES6 arrow function, and ES Next class improvements.

React, as a thriving framework, is also evolving with The Times, constantly improving and adjusting itself with the development of language features.

Finally, here’s a full recap:

Logic of various modes

This paper refers to Cory House’s article: 5 Approaches for Handling this, and extends on this basis. Some of my other React articles:

  • React component design and decomposition thinking
  • Uber mobile web version is not enough to create the ultimate performance to see the real chapter
  • Analyze the Twitter front-end architecture to learn about complex scenario data design
  • React + ES next = ♥
  • React+Redux creates “NEWS EARLY”, a one-page app that understands the true nature of the cutting-edge technology stack
  • React + Redux project example
  • .

Happy Coding!

PS: author Github warehouse, welcome to communicate through various forms of code.