ref – https://www.freecodecamp.org/news/this-is-why-we-need-to-bind-event-handlers-in-class-components-in-react-f7ea1a6f93eb/
Strict mode
In strict mode, the global object is called global. And this is an empty literal object.
However, when you are inside a standalone function, the ‘this’ is undefined and not attached.
1 2 3 4 5 6 7 8 9 10 11 |
"use strict" // by using "use strict" console.log(this) // {} console.log(global) // global object data function tryIt() { console.log(this===undefined) // true } tryIt(); |
Hence, if we do not bind a function in a ReactJS project, the ‘this’ object is undefined.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class Foo extends React.Component{ constructor( props ){ super( props ); } handleClick(event){ console.log(this); // 'this' is undefined } render(){ return ( <button type="button" onClick={this.handleClick}> Click Me </button> ); } } ReactDOM.render( <Foo />, document.getElementById("app") ); |
Thus, that is why you need to bind it in the constructor:
1 2 3 4 |
constructor(props) { super(props); this.handleClick= this.handleClick.bind(this); } |
Creating reference function and binding it in onChange handler
Say we create a handler for onChange. But we want to give it more parameters. How do we do it?
First, understand Apply
First, we create a function where its ‘this’ executes a callMe function.
1 2 3 |
function myChangeHandler (argA) { this.callMe(argA) } |
callMe was not defined, so we use ‘apply’ to have the ‘this’ reference our own custom object.
We put in object with a callMe function like so:
1 2 3 4 5 |
myChangeHandler.apply({ callMe: function(firstArg) { console.log('I got:', firstArg) } }, ['1']); |
When you use apply, you execute myChangeHandler right away and that is why you’ll get the log right away. In myChangeHandler, this.callMe executes right away.
Now, when using bind it DOES NOT EXECUTE RIGHT AWAY. It will return a function reference. You must exeucte it in the future in order to use it.
1 2 3 4 5 6 |
const preBoundMyChangeHandler = myChangeHandler.bind({ callMe: function(firstArg) { console.log('I got:', firstArg) } }, '1') preBoundMyChangeHandler() |
That is why when you’re in the html code, and you need to implement an onChange handler, you need to do this:
1 |
onChange={this.searchWithHandleChange.bind(this, SEARCH_STARTS_WITH)} |
First, when you use bind, it returns a function reference which is what you need. You do not want to execute a function right away. You need to give a reference to a function for future executions. That is why bind works, and call/apply does not work here.
Second, naturally, any values you give, will be designated as the parameter to the handler function
1 2 3 |
searchWithHandleChange(type, event) { ... } |
Hence, the parameter type will have the value SEARCH_STARTS_WITH.
Finally, notice we also have an event object parameter at the very end. The reason why is because when you click in the future, the searchWithHandleChange will be called in the future. The system will dynamically give you an event object along with the click. It will be appended as the last parameter in your param list.