arlyon
arlyon

Reputation: 135

Calling a component function from within a function in Reactjs

I have a component that is laid out like this:

var Entry = React.createClass({
    // executes code on a button press.

    onButtonClick: function (event) {
       // (do stuff)
    },

    // generates the entry list with a button and some info.

    render: function() {
        var entryList= this.props.data.map(function(entry) {
            // (convert timestamp into relative time, add some tags etc)
            return (
                <p> entry.information </p>
                <a onClick={onButtonClick} className="btn right" id={entry.link}>
                    go
                </a>
            );
        });

        // returns the html of the component

        return (
            <div className="entryList">
                {entryList}
            </div>
        );
    }
});

I would like to be able to run the function onButtonClick from within the entryList variable in the render function but I can't seem to figure out how to do it. When running it the console says onButtonClick is not defined.

Uncaught ReferenceError: onButtonClick is not defined

How do I "escape" the function? I think that this.props.data.map(function(items) {}); is what is complicating the issue because I can access it just fine from if I move the button like this

        // returns the html of the component

        return (
            <div className="entryList">
                <a onClick={this.onButtonClick} className="btn right">go</a>
                {entryList}
            </div>
        );
    }
});

Thanks for your help!

Upvotes: 1

Views: 1237

Answers (2)

Rafi Ud Daula Refat
Rafi Ud Daula Refat

Reputation: 2257

The context changes. So you can do this.

var Entry = React.createClass({
    // executes code on a button press.

    onButtonClick: function (event) {
       // (do stuff)
    },

    // generates the entry list with a button and some info.

    render: function() {
      var self = this;
        var entryList= this.props.data.map(function(entry) {
            // (convert timestamp into relative time, add some tags etc)
            return (
                <p> entry.information </p>
                <a onClick={self.onButtonClick} className="btn right" id={entry.link}>
                    go
                </a>
            );
        });

        // returns the html of the component

        return (
            <div className="entryList">
                {entryList}
            </div>
        );
    }
});

or simply

var Entry = React.createClass({
    // executes code on a button press.

    onButtonClick: function (event) {
       // (do stuff)
    },

    // generates the entry list with a button and some info.

    render: function() {
        var entryList= this.props.data.map(function(entry) {
            // (convert timestamp into relative time, add some tags etc)
            return (
                <p> entry.information </p>
                <a onClick={this.onButtonClick} className="btn right" id={entry.link}>
                    go
                </a>
            );
        },this);

        // returns the html of the component

        return (
            <div className="entryList">
                {entryList}
            </div>
        );
    }
});

Upvotes: 1

Michael Parker
Michael Parker

Reputation: 12966

The reason your code isn't working the way you expect it to is because the context this changes inside of the anonymous function passed to map. map takes an optional second parameter, which represents the value of this that the callback will use. So simply adding this as a second argument to map will solve your problem.

var entryList = this.props.data.map(function(entry) {
    ...
}, this);

Developers who use ES2015 can also use an arrow function to automatically bind the correct context of this.

var entryList = this.props.data.map(entry => {
    ...
});

Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Upvotes: 1

Related Questions