响应组件上的 onClick 事件

React onClick event on component

我有一个名为 <SensorList /> 的 React 组件,它有很多子组件 <SensorItem />(另一个 React 组件)。我希望能够在 <SensorList /> 中的每个 <SensorItem /> 上声明一个 onClick 事件。我已尝试执行以下操作:

sensorSelected: function(sensor) {
    console.log('Clicked!');
},

render: function() {
    var nodes = this.state.sensors.map(function(sensor) {
        return (
            <SensorItem onClick={ this.sensorSelected } />
        );
    }.bind(this));

    return (
        <div className="sensor-list">
            { nodes }
        </div>
    );
}

不用说,我的控制台中没有出现任何 "Clicked!"。 Chrome 中的 React inspector 指示注册了一个 onClick 事件,上面的函数体应该是这样。

因此,我得出结论,我无法在实际的 <SensorItem /> 标签上注册 onClick 事件(但我不确定这是为什么)。否则我该如何实现这一目标?

这取决于您的 SensorItem 组件的定义。 因为 SensorItem 不是 native DOM element 但是,就像你说的,另一个 React 组件,这里定义的 onClick 只是一个属性 该组件。您需要做的是,在 SensorItem 组件内部将 onClick 道具传递给 DOM 组件的 onClick 事件:

var SensorItem = React.createClass({
  render: function() {
    return (
      <div className="SensorItem" onClick={this.props.onClick}>
       ...
      </div>
    );
  }
});

问题

正如在另一个答案中所解释的那样,问题是 <SensorItem> React 组件上的 onClick(与本机 DOM 元素相反,例如 <div><p>) 被视为组件 属性 的传递,而不是 DOM 事件处理程序的传递。而且很可能您的 <SensorItem> 组件没有声明 onClick 属性,属性 值会丢失。

解决方案

最直接的解决方案是在 SensorItem 组件上显式添加 onClick 属性,然后将其传递给该组件的根 DOM 元素:

function SensorItem({ prop1, prop2, onClick }) {
  (...)

  return (
    <p onClick={onClick}>
      (...)
    </p>
  );
}

但通常最适合我的解决方案是使用对象解构符号将所有未定义组件的属性分组,然后将它们全部传递给该组件内的根 DOM 元素。这样您就可以传递 onClickonHoverclassName 等,而无需为它们中的每一个定义单独的属性:

function SensorItem({ prop1, prop2, ...rootDOMAttributes }) {
  (...)

  return (
    <p {...rootDOMAttributes}>
      (...)
    </p>
  );
}

无论您使用这两种方法中的哪一种,处理程序现在都可以工作,因为它现在将附加到 SensorItem 的根 DOM 元素:

<SensorItem onClick={...} />