【问题标题】:How to get a onClick to work in a row - reactjs如何让 onClick 连续工作 - reactjs
【发布时间】:2014-10-05 15:51:27
【问题描述】:

我正在尝试获得点击,甚至可以使用reactjs 中的表格。我的第一次尝试是使整行可点击。这是我的代码:

var UserList = React.createClass({
  getInitialState: function() {
    return getUsers();
  },
  handleClick: function(e) {
    console.log("clicked");
  },
  render: function() {
    var users = this.state.users.map(function(user) {
      return (
        <tr onClick={this.handleClick}>
          <td>{user.name}</td>
          <td>{user.age}</td>
          <td></td>
        </tr>
      );
    });
    return(
      <div className="container">
        <table className="table table-striped">
          <thead>
            <tr>
              <th>Name</th>
              <th>Age</th>
              <th>Full Detail</th>
            </tr>
          </thead>
            <tbody>
              {users}
            </tbody>
        </table>
      </div>
    );
  }
});

这不起作用。然后我尝试在表格中添加一个按钮:

<button className="btn" onClick={this.handleClick}>Full Detail</button>

那也没用。我在整个应用程序中都有其他 onClick 工作,但是如何使用表格来完成这项工作?

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    绑定创建一个新对象。因此,如果您为 N 个员工绑定您的函数,那么您创建 N 个新函数的效率很低。更优雅的方法是将函数绑定一次,然后将引用传递给每一行。您的原始代码非常接近。这是我的建议:

     handleClick = e => {
        const user = this.state.users.find(u => u.uuid == e.target.dataset.uui)
        console.log("clicked");
      },
      render() {
        return(
          <div className="container">
            <table className="table table-striped">
              <thead>
                <tr>
                  <th>Name</th>
                  <th>Age</th>
                  <th>Full Detail</th>
                </tr>
              </thead>
                <tbody>
                  {this.state.users.map(user => 
                    (
                     <tr data-uuid={user.uuid} onClick={this.handleClick}>
                       <td>{user.name}</td>
                       <td>{user.age}</td>
                        <td>{user.details || ''}</td>      
                     </tr>
                    )
                  )}
      
                </tbody>
            </table>
          </div>
        );
      }
    });
    
    

    【讨论】:

      【解决方案2】:

      我是新手。这个怎么样?您只需将其包装在另一个函数中,然后该函数将包含闭包范围并正确调用它。

      不知道这是不好的做法还是性能差异,但它似乎有效......

      var users = this.state.users.map(function(user) {
        return (
          <tr onClick={()=>this.handleClick(user)}>
            <td>{user.name}</td>
            <td>{user.age}</td>
            <td></td>
          </tr>
        );}.bind(this);
      });
      

      【讨论】:

      • 事实证明,这通常是一种不好的做法,但尤其是在具有大量行的数据集中,因为只构建了 n 个函数就足够了。我会留下它作为不做的例子
      • 在每次渲染的子道具中添加新功能是一种不好的做法,因为这会改变每次渲染的虚拟 dom 状态。因此,react 必须在每次渲染父组件(表)时重新渲染子组件(tr)。
      【解决方案3】:

      您的问题是创建表格行的用户功能未绑定到您的反应组件。 this 的值将不是您的反应组件,并且 handleClick 不会作为 this 的属性存在。

      试试

      var users = this.state.users.map(function(user) {
        return (
          <tr onClick={this.handleClick}>
            <td>{user.name}</td>
            <td>{user.age}</td>
            <td></td>
          </tr>
        );}.bind(this);
      });
      

      如果你想让它在所有浏览器上工作,或者使用 Underscore 的 bind

      【讨论】:

      • 这完全有道理。我不明白最后一句话,“或者如果你希望它在所有浏览器上工作,用户下划线绑定”?你能给我举个例子吗?
      • .bind 在旧版浏览器中不受支持。 Underscore 是一个流行的库,其中包括对旧版浏览器的绑定支持。
      • 另外,如果您想知道单击了哪个用户行,请将其添加为另一个要绑定的参数:.bind(this, user),并将单击处理程序修改为:handleClick: function (user, e) {
      • 感谢您,抱歉它的旧版本,但要添加到@joakimbeng 解决方案中,在 onclick 上应该如下所示:onClick={ (e) =&gt; this.props.onSelect(e, user)}
      猜你喜欢
      • 2014-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-22
      相关资源
      最近更新 更多