6 Ways to Bind JavaScript’s this Keyword in React, ES6 & ES7
Javascript’s this
keyword is the source of a lot of confusion for many developers every single day. Unlike a language with a rigid class model, it’s not always clear what this
is going to refer to in your code, especially when dealing with callback functions, whose callsites you have no control over.
It’s trivial for some other code to rebind the context of the function you’re working with―using the new
keyword and some of the methods that are built onto Function.prototype
. This introduces an entire class of confusing scenarios and often you’ll see callback driven code scattered with calls to .bind(this)
.
The Problem
Because React uses the this
keyword to reference the component context inside each class, it also inherits this confusion. You’re probably used to seeing code like this inside React components.
this.setState({ loading: true });
fetch('/').then(function loaded() {
this.setState({ loading: false });
});
This code results in a TypeError
because this.setState is not a function
. This is because when the callback to the promise is called, the internal context of the function is changed and this
references the wrong object. Let’s take a look at the ways in which we can prevent this from happening.
The Options
Some of these alternatives are old techniques that have been used in Javascript for years, others are specific to React and some won’t even work in browsers yet, but we’ll explore them all anyway.
1. Alias This
This is approach has been around for a lot longer than React and it involves creating a second reference to the this
at the top level of the component’s scope.
var component = this;
component.setState({ loading: true });
fetch('/').then(function loaded() {
component.setState({ loading: false });
});
This approach is lightweight and very easy to understand for beginners (although it may not be clear why you did it). It gives you a visual guarantee that you’ll be referring to the correct context.
It feels a bit like you’re working against the semantics of the language itself, but it’s a simple solution and it works well.
2. Bind This
The next option we have involves injecting the correct context into our callback function at runtime.
this.setState({ loading: true });
fetch('/').then(function loaded() {
this.setState({ loading: false });
}.bind(this));
All functions in Javascript have a bind method, which allow you to specify the value for this
. Once a function has been “bound” the context can’t be overriden, meaning that we have a guarantee that this
will refer to the correct thing.
This approach is a little bit harder to understand for other programmers and if you’re working with deeply nested, asynchronous code, then you’ll find yourself having to remember to bind each function as you go.
3. React Component Methods
React allows you to define arbitrary methods on your component classes and these methods are automatically bound with the correct context for this
when you create your components with React.createClass
. This allows you move your callback code out onto your component.
React.createClass({
componentWillMount: function() {
this.setState({ loading: true });
fetch('/').then(this.loaded);
},
loaded: function loaded() {
this.setState({ loading: false });
}
});
This can be a very elegant solution if you aren’t doing much work in your component (you probably shouldn’t be, either!). It allows you to use named functions, flatten your code and forget about having the correct context. In fact, if you try to .bind(this)
onto a component method, then React will warn you that you’re doing unnecessary work.
Continue reading %6 Ways to Bind JavaScript’s this Keyword in React, ES6 & ES7%
LEAVE A REPLY
You must be logged in to post a comment.