user3134477
user3134477

Reputation:

Why one function requires binding and the other doesn't?

I just started learning React and JavaScript.
While going through the tutorial, I got to this example code of a component, which creates a toggle button:

class Toggle extends React.Component {
    constructor(props) {
        super(props);
        this.state = {isToggleOn: true};
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        this.setState(prevState => ({
            isToggleOn: !prevState.isToggleOn
        }));
    }

    render() {
        return (
            <button onClick={this.handleClick}>
                {this.state.isToggleOn ? 'ON' : 'OFF'}
            </button>
        );
    }
}

The way I see it, both handleClick and render functions use the class's this object, which is out of their scope (right?).

So why do I only need to bind it into handleClick?

Upvotes: 1

Views: 205

Answers (2)

Prakash Sharma
Prakash Sharma

Reputation: 16472

In any react class, functions like componentWillMount, componentDidMount, render etc are called by react internally while rendering the elements and we never call these methods.

Now since the scope is decided while calling, it's react's job to call/bind these methods with appropriate scope.So we do not need to bother about these functions.

However the other functions like handleClick in above example is a method made by us and react does not know anything about it. Also this method's call is defined by us (i.e. when the button is clicked). So here it is our job to call/bind this method with right scope.

That is why we only bind handleClick and not render function in above example.

Upvotes: 0

Soviut
Soviut

Reputation: 91545

Javascript assigns scope when calling, not when defining. You need to bind() your handleClick() method to the class so that when it's called from the the template it can still access the class' scope via this.

React templates are compiled into javascript functions, so if you didn't bind() your onClick={this.handleClick} handler would be scoped to the template function that called it. In your case, it would refer to the button that was clicked.

If your event handler never referred to this it wouldn't need binding, but since you're calling this.setState() then binding is necessary to keep the handler aware of the class scope.

Upvotes: 2

Related Questions