React剥离onclick

时间:2017-02-09 21:25:02

标签: reactjs

我有以下React组件:

class PlayerRow extends Component {
    activateKey(){
        $(this).addClass('active')
}
render() {

   return (
               <div className="row-par">
                   <div className="details-cont">
                   </div>
                    <div className="key-cont">
                        <div onClick={this.activateKey} className="key"></div>
                        <div onClick={this.activateKey} className="key"></div>
                        <div onClick={this.activateKey} className="key"></div>
                    </div>
               </div>
       )

}
}

我试图在点击嵌套div时执行函数activateKey,但每当我渲染应用程序时,我的onclick属性都会从所有div中删除。为什么会这样?

2 个答案:

答案 0 :(得分:1)

React绑定事件侦听器本身,因此onClick不会直接导致DOM中的onclick属性。但是,您的代码实际上有效(请参阅代码段)。

class PlayerRow extends React.Component {
    activateKey() {
        console.log('ddd')
}
render() {

   return (
               <div className="row-par">
                   <div className="details-cont">
                   </div>
                    <div className="key-cont">
                        <div onClick={this.activateKey} className="key">asd</div>
                        <div onClick={this.activateKey} className="key">qwe</div>
                        <div onClick={this.activateKey} className="key">zxc</div>
                    </div>
               </div>
       )

}
}

ReactDOM.render(
  <PlayerRow/>,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

我建议2件事,使用.bind(this)作为动作处理程序甚至更好,使用箭头函数,因为它默认继承范围。

来自反应文档:

handleClick = () => {
  console.log('this is:', this);
}

请参阅:https://facebook.github.io/react/docs/handling-events.html

第二件事 - 不要使用jQuery。您正在使用React来管理DOM,并且jQuery默认会产生副作用,因此,它会干扰反应的工作方式。 React会自动根据组件的状态或道具呈现你的视图,它的优化非常棒,jQuery既不会编辑道具也不会编辑状态,所以你不会利用任何反应很酷的东西。

对于您想要实现的目标,您可以为操作处理程序提供一个参数,告诉您单击了哪个块onClick={() => activateKey(1)}。在处理程序中将活动ID保存在本地状态,并根据条件的id是否与密钥ID匹配,有条件地为块提供类。这是我的想法。

答案 1 :(得分:0)

在render方法中使用ES6箭头函数或.bind()会给组件增加不必要的开销。你真的应该.bind(this)到构造函数中的方法,如:

import React, { Component } from "react";

export default class Demo extends Component {
    constructor(props) {
        super(props);

        this.activateKey = this.activateKey.bind(this);
    }

    activateKey() {
        console.log("ddd");
    }

    render() {

        return (
            <div className="row-par">
                <div className="details-cont"></div>
                <div className="key-cont">
                    <div onClick={this.activateKey} className="key">asd</div>
                    <div onClick={this.activateKey} className="key">qwe</div>
                    <div onClick={this.activateKey} className="key">zxc</div>
                    </div>
                </div>
        );
    }
}

如果这样做,在类初始化阶段,每个方法只执行一次绑定操作。如果在render方法中使用ES6箭头函数或.bind(this等等),则会在每次重新渲染时从每个具有onClick事件的元素执行绑定。

你应该在render方法中使用.bind(this等等)或ES6箭头函数的唯一时间是你需要将一个非click事件传递给一个函数。