Sangit Dhanani Sangit Dhanani - 2 months ago 9
React JSX Question

onClick function doesn't bind in reactjs

I'm a newbie to reactjs and using click handler to show/hide some div's in my webpage. The onClick method of button doesn't call the required function.
Here is a snippet of the code.

showPartsInfo: function(e){
console.log(e+" here in parts ");
this.setState({showInfo:!this.state.showInfo});
}

return <div>
<h3>Search Parts:</h3>
<input type="text" value={this.state.searchString} onChange={this.handleChange} placeholder="Type here" />
{
libraries.map(function(l){
return([
<div className="container">
<div className="row">
<div className="col-sm-6">
<button type="button" onClick={this.showPartsInfo}>{l.name}</button>
{ showInfo ? <Results /> : null }
</div>
<div className="col-sm-6">
<a className="button btn2 cur">Move</a>
</div>
</div>
</div>
]);
})
}
</div>
}


I'm able to log when onChange is called but can't log when onClick is called.

Answer

Inside your .map function, you're creating a function, so you're executing all the code inside the scope of that function. So, this.showPartsInfo doesn't exist, because this is pointing to the function itself.

You have to bind that function to the component context, using .bind() like this:

                libraries.map(function(l){
                return([
                    <div className="container">
                    <div className="row">
                        <div className="col-sm-6">
                                 <button type="button" onClick={this.showPartsInfo}>{l.name}</button>
                                 { showInfo ? <Results /> : null }
                        </div>
                        <div className="col-sm-6">
                            <a className="button btn2 cur">Move</a>
                        </div>
                    </div>
                    </div>
                    ]);
                }.bind(this))

(Notice the last line). More on this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

You can also pass the scope as a second argument, so instead of using bind, you do this:

libraries.map(function(l){...}, this);