StrangeManInMask
StrangeManInMask

Reputation: 213

onClick handler doesn't wait for click instead prints all the information immediately

I'm learning React and didn't find any solutions from the internet how to solve this or why this is even behaving like it is.

var people = [
    {id: 1, name: 'Jack'}, 
    {id: 2, name: 'John'}, 
    {id: 3, name: 'Patrick'}
]

var Hello = React.createClass({
    handlePerson: function(id){
        alert(id);
    },
    render: function() {
        var self = this;
        var listPersons = this.props.names.map(function(p){
            return <li onClick={self.handlePerson(p.id)}> {p.name} </li>
        });
        return (
            <ul>
                {listPersons}
            </ul>
        )
    }
});

React.render(<Hello names={people} />, document.getElementById('container'));

Why my handlePerson function is immediately executed in run time printing "1, 2, 3" instead of that it would wait that user clicks on li element?

https://jsfiddle.net/69z2wepo/12784/

Upvotes: 0

Views: 578

Answers (1)

Colin Ramsay
Colin Ramsay

Reputation: 16476

It's because you're invoking it rather than passing it as a handler. You need to do this:

return <li onClick={self.handlePerson}> {p.name} </li>

However since you also want to pass an argument, you need to use bind:

return <li onClick={self.handlePerson.bind(null, p.id)}> {p.name} </li>

In a React if you pass null as the scope (the first argument to bind) then the scope of the handler will automatically be set to the component. More on bind:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind

It's worth mentioning that this doesn't really have anything to do with React and you'd have the same problem if you were passing an event handler like this in vanilla JS.

Upvotes: 2

Related Questions