Have you ever experience reading an existing React code base and wondering why is there a need for this.functionName = this.functionName.bind(this)
in the React component constructor? And what make it more confusing is when not all function has binding syntax.
If you looking for a quick-fix this problem, one of the solution (and is actually the best solution) would to simply turn all your function to arrow function. Arrow function takes
this
from the outer lexical scope. Here’s an example based on the above. You will need to add this to your babel config
It’s how JavaScript works. There are plenty of articles elsewhere explaining how JavaScript and especially what .bind()
means(which is how this context get passed over), and how JavaScript bind for you. Instead, I’ll go straight to the abyss in JavaScript.
Reference code for the below
Deep down in JavaScript, when you do cat.sayHi()
JavaScript returns a Reference Type value of (cat, "sayHi", true)
. ReferenceType(base, name, strict) where
use strict
When JavaScript returns Reference Type value of (cat, "sayHi", true)
, it means the property sayHi
will have cat
as this
context. The last parameter is to decide the value ofthis
if the object is undefined
. It will be undefined
if true
or global window object
if false.
However when you do var dogHi = dog.sayHi
, JavaScript discard away the Reference Type value and only store the function into dogHi. As a result when you execute dogHi
, it does not know that the value ofthis
is dog and throw cannot read property 'name' of undefined
Referencing back to the earlier example, when we do onClick={this.handleClick}
, we are basically assigning callback a function similar to us doing var dogHi = dog.sayHi
.
And to solve this, we could use arrow function rely on outer lexical context (the Animal class) where the function was created:
I hope this helps, arrow functions are useful in many more context. I’ll leave those in another article.