Why and when do we need to bind functions and eventHandlers in React?

Binding is not something that is specifc to React, but rather how this works in Javascript. Every function / block has its own context, for functions its more specific to how its called. The React team made a decision for this to not be bound on custom methods on the class (aka not the builtin methods like componentDidMount), when adding ES6 support (class syntax).

When you should bind the context depends on the functions purpose, if you need to access props, state or other members on the class, then you would need to bind it.

For your example, each is different and it depends on how your component is set up.

Pre binding to your class

.bind(this) is used to bind the this context to your components function. However, it returns a new function reference each render cycle! If you don’t want to bind on each usage of the function (like in a click handler) you can pre-bind the function.

a. in your constructor do the binding. aka

class SomeClass extends Component{
    constructor(){
        super();
        this.someEventHandler = this.someEventHandler.bind(this);
    }
    someEventHandler(event){
    }
    ....
} 

b. make your custom functions on the class fat arrow functions. aka

class SomeClass extends Component{
    someEventHandler = (event) => {
    }
    ....
}

Runtime binding to your class

few common ways to do this

a. you can wrap your components handler function with an inline lambda (fat arrow) function.

onChange={ (event) => this.someEventHandler(event) }

this can provide additional functionality like if you need to pass additional data for the click handler <input onChange={(event) => { this.someEventHandler(event, 'username') }>. The same can be done with bind

b. you can use .bind(this) as described above.

onChange={ this.someEventHandler.bind(this) }

with additional params <input onChange={ this.someEventHandler.bind(this, 'username') }>

If you want to avoid creating a new function reference but still need to pass a parameter, its best to abstract that to a child component. You can read more about that here

In your examples

// 1
return <input onChange={this.someEventHandler.bind(this)}>

This is just doing a runtime event handler bind to your class.

// 2
return <input onChange={(event) => this.someEventHandler(event) }>

Another runtime bind to your class.

// 3
return <input onChange={this.someEventHandler}>

You are just passing the function as the callback function to trigger when the click event happens, with no additional parameters. Make sure to prebind it!

To summarize. Its good to think about how to optimize your code, each method has a utility / purpose depending on what you need.

Leave a Comment