1

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!

1
  • You should set this for .map - this.props.data.map(function(entry) {}, this) Commented Aug 29, 2016 at 15:38

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your detailed response.
1

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>
        );
    }
});

6 Comments

it is not necessary store this to variable. You can set this for .map - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… - just pass second argument!
thank. Yes that is another way. i am adding that in that answer.
Arrow functions are also another option.
@michael he is not using es6 in his code as we can see his source code.
@Michael Parker yes, however I don't see where author uses ES2015.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.