React.js中的OnClick事件绑定

时间:2014-12-10 09:21:17

标签: javascript reactjs

我希望在点击该div或同一div的任何子元素时传递父div ID。但我无法实现它。请告诉我我在哪里弄错了。代码如下:

viewMore: function(i,j){
        console.log('You clicked: ', i  );
    },

render : function(){
  var attributeId = "groups_";
  attributeId+= index;
  return(
  //parent div
    <div className="groups" id={attributeId} onClick={this.viewMore}>
        <div className="floatLeft"> Group Name: <h3>My Name</h3></div>
            <span className="floatRight typeCd">POC</span>
        <div className="clearfix"> Key Attributes: 
            <ul>
                <li> POC 1</li>
            </ul>
        </div>
    </div>
    )
};

5 个答案:

答案 0 :(得分:49)

viewMore = (i,j) => () => {
    console.log(i,j)
}

要将参数传递给事件处理程序,我们需要使用 currying 。 使用上述方法,在调用render时,不会一直创建新函数。

答案 1 :(得分:32)

由于我在多个地方看到了这些建议,我也会将我的评论转移到答案中,以提供额外的观点:

class TestComponent extends React.Component {
  constructor() {
    super();
    this.onClick = this.handleClick.bind(this);
  }

  handleClick(event) {
    const {id} = event.target;
    console.log(id);
  }

  render() {
    return (
      <div>
        <h3 id={this.props.id} onClick={this.onClick}>
          {this.props.name}
        </h3>
      </div>
    );
  }
}

这允许:

  1. 避免不必要的约束
  2. 以更多React-ive方式访问id和其他任何属性。
  3. 当然,上面的例子假设您收到id作为道具,但您也可以进行必要的操作。

    更新1 - 2016年11月28日

    从上面的评论中添加了CodePen的链接。

    更新2 - 2017年3月30日

    如上所述,如果您使用React.createClass 来定义组件,则无效。你没有一个构造函数来解决这个问题。如果你不介意一点丑陋,你可以使用其他生命周期方法。

    话虽如此,它是2017年。使用ES6,好吗?!

    更新3 - 2017年5月12日

    如果您使用class properties transform,则可以进一步简化:

    class TestComponent extends React.Component {
      onClick = (event) => {
        const {id} = event.target;
        console.log(id);
      }
    
      render() {
        return (
          <div>
            <h3 id={this.props.id} onClick={this.onClick}>
              {this.props.name}
            </h3>
          </div>
        );
      }
    }
    

    更新4 - 2018年2月4日

    由于bind和V8中的朋友的改进(Chakra等也可能),你可能会更好地使用this.click.bind(this)或者在传递给{{1时将它包装在箭头函数中}}

    为什么?

    之前的方法仅仅是出于性能原因而创建的,它为将函数动态注入到组件的原型中提供了一些可能性。

    注1 - 2018年4月14日

    请记住,Update 4中提到的方法仍会引入一些性能问题,因为在onClick次传递时,render会创建一个新函数。反过来,这将逐渐渗透到子组件并导致不必要的重新渲染,因为函数每次都会更改。

    当你内联传递箭头函数时会发生同样的事情。

    所有其他方法,比如使用类属性,会破坏你的继承(你应该避免,但仍然如此),原因是,目前,Babel将它们转换为“on-instance”函数,不在原型链上。

    所以,这个:

    bind

    变为:

    class Person {
      printA = () => { console.log('a') }
    }
    

答案 2 :(得分:15)

我在这里为ES6做了更新的答案: https://stackoverflow.com/a/35748912/76840

基本上,您可以使用箭头函数表达式,它具有保留this的好处:

onClick={(event)=>this.viewMore(attributeId, event)}

在此编辑中,如果您使用启用了stage-2的Babel,则可以使用如下属性:

// Within your class...
viewMore = (event) => { /* ... */ }
// Within render method in your JSX
onClick = {this.viewMore}

答案 3 :(得分:5)

您可以使用currying功能。

<强> ES5:

viewMore(param) { // param is the argument you passed to the function
    return function(e) { // e is the event object that returned

    };
}

<强> ES6

viewMore = param => e => {
  // param is the argument you passed to the function
  // e is the event object that returned
};

就这样使用它:

onClick={this.viewMore("some param")}

答案 4 :(得分:1)

以下是对以前答案的更新和概述:

  1. @HenrikAndersson使用onClick = {this.viewMore.bind(this,attributeId)} 虽然这种方法达到了目的,但它使用了许多不舒服的绑定语法。
  2. 使用public class field提到的@ZenMaster。此解决方案具有或多或少的相同性能,还带有更好的语法。但是当我们必须传递参数时,它变得棘手。

    class TestComponent extends React.Component {
      onClick = (event) => {
        const {id} = event.target;
        console.log(id);
      }
    
      render() {
        return (
          <div>
            <h3 id={this.props.id} onClick={this.onClick}>
              {this.props.name}
            </h3>
          </div>
        );
      }
    }
    
  3. 上述方法会跳过传递参数,而是使用自定义属性来访问点击处理程序中所需的数据。

    更好的解决方案是:

    class MyComponent extends React.Component {
    
        handleClick = (item) => (e) => {
            e.preventDefault()    
            console.log(`This has access to item ${item}! and event(e)`)
        }
    
        render(){
            const item={ id:'1', value: 'a' }
            return(
                <button onClick={ this.handleClick(item) }  >Click</button>
            )
        }
    
    }
    

    参考:Handle events by arrow functions in React app