Ad

Runtime Context (this) Of The Function Comes From This.props

- 1 answer

We always use like this:

var MainComponent = React.createClass({
    changeHandler() {
        this.setState({
            foo: 'bar';
        })
    },
    render() {
        return (<SubComponent onChange={this.changeHandler} />)
    }
})
var SubComponent = React.createClass({
    render() {
        return (<button onClick={this.props.onChange}>Change</button>)
    }
})

when we call this.props.onChange in SubComponent, we actually call changeHandler of MainComponent.
I suddenly realize that the context of changeHandler has been changed when pass to SubComponent using this.props, the this inside changeHandler should have been changed to this.props.
But as we all know, when we call changeHandler inside Subcomponent, the this in changeHandler is still MainComponent.
So I guess there may be some 'binding' when when pass function from MainComponent to SubComponent using this.props. The context of changeHandler is bound to MainComponent.

I add an console.log(this.props) in SubComponent's render, and I find some properties been add to this.props.onChange:

  1. __reactBoundArguments: null
  2. __reactBoundContext: point to Constructor MainComponent
  3. __reactBoundMethod: point to function changeHandler

I think these are about the 'binding', but I don't know how they actually work.

Could someone please tell me something detail about this context binding, it's really nag me a lot. How does React do that?

Ad

Answer

When you define your components with React.createClass() there's a bit of auto-binding behind the scenes.

Your onChange={this.changeHander} effectively becomes onChange={this.changeHandler.bind(this)}. The reason for this is because it's generally what you want. This is documented here:

https://facebook.github.io/react/blog/2013/07/02/react-v0-4-autobind-by-default.html

Note however that if you define your components using the ES6 class syntax, this auto-binding does not occur. This was a deliberate decision to keep the behaviour the same as typical JavaScript classes. This is documented here:

https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html

Autobinding

React.createClass has a built-in magic feature that bound all methods to this automatically for you. This can be a little confusing for JavaScript developers that are not used to this feature in other classes, or it can be confusing when they move from React to other classes.

Therefore we decided not to have this built-in into React's class model. You can still explicitly prebind methods in your constructor if you want.

Ad
source: stackoverflow.com
Ad