Ben Liger Ben Liger - 1 month ago 5
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.

Comments