onClick事件处理程序在加载时调用,而不是单击

时间:2016-10-17 11:47:14

标签: javascript reactjs ecmascript-6

我是React的新手,在尝试触发已设置为道具的功能时遇到了问题。这是我的组成部分:

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

我试图触发的事件是playSampleAction。当我加载页面时,事件似乎会触发,但是当我点击时则不会触发。我尝试在.bind(this)的末尾添加onClick,但是sill没有执行点击操作。值得注意的是,点击时没有控制台错误。

2 个答案:

答案 0 :(得分:1)

您立即调用该函数并传递onClick返回值,这使它似乎在加载时运行。您必须传递函数的引用,而不是调用:

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

这样做是使用绑定this上下文和其他参数的Function.prototype.bind,返回一个新的可调用函数,并应用这些参数。来自文档:

  

bind()方法创建一个新函数,在调用时,将其this关键字设置为提供的值,并在调用新函数时提供任何前面提供的给定参数序列。

在上面的代码中,我为undefined传递this和函数参数。因此,该函数不会立即被调用,但是a函数将被传递给onClick事件而不是传递返回值的调用。

注意:如果这是您要使用playSampleAction的唯一地方,请将其绑定在类构造函数中,以避免在点击时创建新函数。

另一个(在我看来,首选)解决方案是使用ES6 arrow functions

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

然后,您可以添加所需的任何参数。因为箭头函数只是匿名函数的较短语法,所以传递可调用函数 - 而不是调用。这将在点击时正确执行。

答案 1 :(得分:0)

playSampleAction必须返回一个函数,让它在点击时触发:

playSampleAction(sample,sampleId) {
   return function(event){
      console.log(sample);
   }
}

在渲染时评估React道具。因此,将会触发支柱中调用的每个函数,如onClick。你想要的是给onClick回调,以便仅在点击时触发它。所以playSampleAction必须返回一个函数