When I'm teaching React to developers, one thing that comes up often is dealing with a common error. But here's the interesting thing: it's not running into the error that comes up all the time, its how to deal with it that surprises them. I've always wanted to have something to point to that the scenario & why one option is better than others, even though there are plenty of ways to address the issue. That's what this post is!
Let me start that I'm not the first person to write about this. Spend a few minutes exercising your Google-Fu and you'll find plenty of others have written about the same thing.
If you've worked with React, you've probably written a component like this:
In this very simple component, you are accessing a member from the class from the event handler. You think
this is pointing to the
Sample class, but what you get is a nasty error. TypeError: Cannot read property ‘foo’ of undefined
Why? What the
this keyword is bound to depends on where it is defined. In this case,
this reverts to its default binding. In the case where you are running in non-strict mode, this is the global window object, but in the case of strict mode, this is
So how do you get around this? You have two options, one of which has two flavors.
Option 1: Using Explicit Hard Binding
This is the easiest to understand, but it also isn't the best option. In this option you explicitly bind the
this value to the thing you want it to refer to in a function:
Now, by just adding that single line in the constructor of your component, this will refer to the component within your event handler function.
While this approach works, there are two issues with it:
- Isn't terribly intuitive: It isn't a great practice to have code somewhere in your project that modifies what other code elsewhere in your project does. You've got your event handler in one place, then somewhere completely different in the same file you've got a single line that modifies how that code behaves. Sure, it works, but it's not a great practice.
- Isn't ideally performant: When you bind the current component to the method, you're binding the whole thing. Let's say you have ten of these buttons on the page. That means you are binding 10 instances of this component to the function. While it won't make a big impact in this simple example, some complex components may have more of an impact.
Option 2: Use Arrow Functions
Arrow functions don't have to worry about this. This is because when you use an arrow function, the event handler is automatically bound to the component instance so you don't need to bind it in the constructor.
When you use an arrow function you are binding
this lexically. According to the definition taken from Stack Overflow, lexically “means that a variable defined outside a function can be accessible inside another function defined after the variable declaration”.
There are two ways you can do this. I prefer to use the public class fields syntax. In this scenario, I like to think that I've assigned code to a variable and I'm using the variable in the handler reference. Notice how the declaration of the handler is written. An arrow function is used to assign the code to a variable that's called as the handler.
The other way is by including the arrow function in the callback. Here, you move the arrow function syntax from the previous snippet from the definition to where it's used:
Whichever way you prefer, I'd pick at least one of the latter two options for your components.comments powered by Disqus