Then I researched this binding in React

Then I researched this binding in React

I’ve been learning javascript and react library in-depth for a couple of weeks as of now and one thing that always keeps bothering me is the event callbacks or the functions passed down to children ( generally stateless ) are always somewhat magically needed to be BIND to the original class/component.

I asked couple of people about why this is needed and didn't get a satisfactory answer from most of them. Then, I started to research what is the binding thing in react and why it is needed.

Then I started reading a couple of books and articles and after being confident enough to have known about the classes and objects in javascript, I can I am pretty comfortable to all this.

First, let’s clear up some terminologies.

Prototypes It’s a javascript way of passing attributes/properties to its’ children. Whenever javascript starts searching for methods/properties not found in a child class, its concept of inheritance is it starts following the prototype chain and stops on the first entry matched.

Call Stack When a new function is called it’s pushed onto the call-stack and javascript execution model executes it passing all the required arguments and properties.

Call Site The actual place where you call your function is called callsite which is also by default bound to the called function as this

Now, let’s start with a basic class.

class C{

    constructor(name) { this.name = name }


    thisIsAFunction(){
        console.log(this.name);
    }

}

So, this is what it compiles down into when you convert it into es5 classes.

"use strict";

var C = /*#__PURE__*/function () {
  function C(name) {
    this.name = name;
  }

  var _proto = C.prototype;

  _proto.thisIsAFunction = function thisIsAFunction() {
    console.log(this.name);
  };

  return C;
}();

So, basically, a new function is created called C, its prototype is saved to another variable and an attribute or method called thisIsAFunction is attached to its prototype so now when javascript goes on in search of methods, it follows the path of thisIsAFunction. And in the end C is returned but the whole function is immediately invoked and saved in C.

Okay, let’s look at it one by one. The ‘this’ is the main boogeyman in this code and in this article as a whole.

So, there’s two things to take care of now i.e. call-site and call-stack.

function C(name){
  console.log(this);
  console.log(this.name);
}

So, what do you expect to be output ?

Let’s visualize the execution model followed by your javascript engine to run this piece of code. First your interpreter goes on executing whatever is in the global scoping.

Next, whenever it shows a call to a function. The function is pushed into the call-stack with all its arguments and properties and stuffs. So, when the code is inside the execution of C function.

The item on top of call-stack is C. And the place where function is called is global or window or globalThis. Now, what ‘this’ is evaluated is not to the original function but the actual place where function is called which is also called as call-site.

So, When I call this function, this is attached to place of call i.e. globalScope or undefined if you’re in strict mode.

You can go on and try that piece of code and you will see it will print your window or globalThis on node environment. and this.name will be undefined now, let’s tweak it’s call a little bit.

var name = 'mahesh'

function C(name){
  console.log(this);
  console.log(this.name);
}

C();

It should print mahesh. Now recall what I said earlier, this is bound to call site. So, your global variable exists in this. You can look on the this object to find name: “Mahesh” existing there.

With that being said, if you try to modify this.name inside the function it will also be modified.

Now, let’s see what this means when it’s an object constructed from a class. Or called as new binding.

class TestClass{

constructor() { this.name = "ram"; }

testMethod() { console.log(this.name); }

}

Now, when I create a object from this class using new binding and call it.

const obj = TestClass();
obj.testMethod();

This will print expected result.

But keep in mind, javascript doesn’t bind this in compile time i.e. testMethod doesn’t knows it’s this should always point to the object when its detached from it’s main class.

const extractedMethod = obj.testMethod;
extractedMethod(); //**this **is undefined

So, with that being said, this is not attached to your class or object but it’s referenced whenever it’s being executed i.e. obj.testMethod() here obj behaves as this.

But this is not the case with other modern programming languages which confuses most of the other language programmers.

Now, we are near to the end in this journey.

const extractedMethod = obj.testMethod;

You can do this it’s completely fine but keep in mind your method is not attached to your class. It’s sitting freely somewhere in javascript virtual memory world.

const extractedMethodWithThis = obj.testMethod.bind(obj);

What this does is your testMethod is now bound to always use obj as context.

Even if you pass an object when calling it will never change this context from being obj.

//try this
extractedMethodWithThis.call(someOtherObject);

This won’t work because it’s bound to apply the context as obj whenever it’s called.

Now, adding this all up knowledge. Whenever you make a Class Component in React.

Your piece of code ( method ) from your class is not called just after instantiating the object but passed along extracted from the object.

const yourComponentHandler = yourComponentObject.handleClick;
react.bindToClicks(yourComponentHandler)

Now, whenever your handler is called it lost your context of being this as your object, so it needs to find that every time. So,

YOU BIND IT TO ALWAYS POINT TO YOUR OBJECT !