g_b
g_b

Reputation: 12438

Can't call function in parent component from child component using React

I have 2 files:

grid-body.jsx (GridBody) and grid-row.jsx (GridRow)

In GridBody, I declared a function showAlert which I pass to every GridRow:

var GridBody = React.createClass({
    showAlert: function(msg) {
        alert(msg);
    },

    render: function() {
        var rows = this.props.rows.map(function(li) {
            return (
                <GridRow showAlert={this.showAlert} />
            );
        });

        return (
            <div>
                {rows}
            </div>
        );
    }
});

And in GridRow:

var GridRow = React.createClass({
    toggle: function() {
        this.props.showAlert('HEY');        // -----> ERROR - not a function
    },

    render: function() {
        <div>
            <a href="#" onClick={this.toggle} />
        </div>
    }
});

I'm trying to call the showAlert from parent and based on the examples I've seen, this is how to do it but I can't make it work.

Upvotes: 0

Views: 351

Answers (2)

lorefnon
lorefnon

Reputation: 13095

The context of the function passed to map in render method of GridBody is window and not the component. You can bind the interatee to get the behavior you want:

render: function() {
    var rows = this.props.rows.map(function(li) {
        return (
            <GridRow showAlert={this.showAlert} />
        );
    }.bind(this));

    return (
        <div>
            {rows}
        </div>
    );
}

Upvotes: 0

Dan O
Dan O

Reputation: 6090

you're using the wrong value for this inside of GridView.render. Either pass it explicitly to Array.map() (see the docs for how to do that) or assign this to some new variable at the very top of render() and reference that instead.

Here is a really, really great SO comment as to why this happens, as well as some other alternative workarounds if neither of the above work for you.

Upvotes: 2

Related Questions