Ben Liger Ben Liger - 2 months ago 13
React JSX Question

onClick event handler called on load as opposed to on click

I'm new to React and have come across an issue when trying to trigger a function that has been set as a prop. Here is my component:

class SamplesInnerLrg extends Component {
playSampleAction(sample,sampleId) {
console.log(sample);
}
render() {
return <div className="samples-container-inner-styling">
{

this.props.loadAllInitSamples.map((sample) => {
return (
<div key={sample.id} className="sample-comp-lge">
<div className="sample-comp-lge-head-wrap">
<div className="sample-comp-lge-audio" id={sample.id} ref={sample.id} onClick={this.playSampleAction(sample,sample.id)}>
<audio preload="auto" className="audioTag">
<source src={sample.soundSource} type="audio/wav" />
</audio>
</div>
<div className="sample-comp-lge-header">
<span className="sample-comp-lge-Name"><h1>{sample.sampleName}</h1></span>
<span className="sample-comp-lge-id"><h2><a href="#">{sample.sampleFamily}</a></h2></span>
<div className="sample-comp-lge-owner-cont">
<div className="sample-comp-lge-owner-inner">
<a href="">{sample.uploader}</a>
</div>
</div>
</div>
</div>
<div className="sample-comp-lge-bottom-wrap">
<div className="sample-comp-lge-tags-cont">
<div className="sample-comp-lge-tag">
<ul className="sample-tags-list">
{
sample.tags.map((tag) => {
return (

<li key={tag}><a href="#">#{tag}</a></li>
)
})

}
</ul>
</div>
</div>
</div>

</div>
)
})
}
</div>
}
}


The event I'm trying to trigger is
playSampleAction
. The event seems to fire when I load the page but not when I click. I tried adding
.bind(this)
at the end of the
onClick
but sill doesn't do the click action. Worth noting there are no console errors when I click.

Answer

You invoke the function immediately and pass onClick the return value, which makes it seem to run on load. You must pass a reference of the function, not invocation:

onClick={this.playSampleAction.bind(undefined, sample, sample.id)}

What this does is use Function.prototype.bind which binds the this context and other arguments, returning a new callable function with those arguments applied. From the documentation:

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

In the code above I pass undefined for this , and the function arguments. Thus, the function will not be immediately invoked, but the a function will be passed to the onClick event instead of an invocation which would pass the return value.