WalnutZ
WalnutZ

Reputation: 35

react.js: How to bind passed-in event handler's this to child component?

here's my code:

var Outer = React.createClass({
    clickHandler: function(){
        console.log(this.props.name);
    },
    render: function() {
        return <div><Inner name="inner" clickHandler={this.clickHandler} /></div>;
    }
});

var Inner = React.createClass({
    render: function(){
        return <div onClick={this.props.clickHandler}>This is Inner.</div>
    }
});

what i wanna do here is to print out the Inner's name. but the real result of this code always prints out the name of the Outer. I think if caused by the 'this'. How can I bind the 'this' to Inner?

Upvotes: 0

Views: 1886

Answers (3)

mfeineis
mfeineis

Reputation: 2657

Edit

The usecase in the question is a different one than reusing a function - where you would use mixins. It's rather providing a callback to a child node.

This sounds like a perfect use case for mixins. Create a mixin for your functionality:

var myClickHandlerMixin = {
    clickHandler: function () { /* ... */ }
};

var Outer = React.createClass({
    mixins: [myClickHandlerMixin],
    render: function() {
        return <div><Inner name="inner" onClick={this.clickHandler} /></div>;
    }
});

var Inner = React.createClass({
    mixins: [myClickHandlerMixin],
    render: function(){
        return <div onClick={this.clickHandler}>This is Inner.</div>
    }
});

Upvotes: 1

Silfverstrom
Silfverstrom

Reputation: 29322

Edit: Note that you can not bind this between components in React.

You could have a middle-function that sends back the property. This might be to recommend, since you explicitly can safe check the callback method that was passed as a prop(Which makes your code more portable).

var Outter = React.createClass({
    clickHandler: function(innerName){
        console.log(innerName);
    },
    render: function() {
        return <div><Inner name="inner" clickHandler={this.clickHandler} /></div>;
    }
});

var Inner = React.createClass({
    _clickHandler : function() { 
        /*
        Here you could add some validation that you truly have a callback in your props.
        if(_(this.props.clickHandler).isFunction() ) {
        }
        */
        this.props.clickHandler('innerName');
    },
    render: function(){
        return <div onClick={this._clickHandler}>This is Inner.</div>
    }
});

Upvotes: 2

Anders Ekdahl
Anders Ekdahl

Reputation: 22933

You should pass what Outer needs explicitly from Inner. Both because that's basically your only option, and because it makes the intention more clear.

Something like:

var Outter = React.createClass({
    clickHandler: function(name){
        console.log(name);
    },
    render: function() {
        return <div><Inner name="inner" clickHandler={this.clickHandler} /></div>;
    }
});

var Inner = React.createClass({
    render: function(){
        return <div onClick={this.props.clickHandler.bind(this, 'Inner')}>This is Inner.</div>
    }
});

Upvotes: 0

Related Questions