ReactJS:始终将道具转移到子组件

时间:2015-12-10 05:34:40

标签: reactjs

我有一个更高阶的组件来跟踪任何组合组件的mouseover事件。它大致是这样的:

(Component) => class TrackMouseOver extends React.Component {
  handleMouseOver = (e) => {
    console.log('Mouse over!');
  };

  render() {
    return <Component {...this.props} onMouseOver={this.handleMouseOver}/>;
  }
};

但是,由于React组件本身不绑定到DOM事件,因此效果不佳。除非组件处理onMouseOver道具,否则上述HOC将无效。

在不破坏React组件的黑盒特性的情况下,总是将props转移到子元素是否更好?如果是,这样做会对性能产生重大影响吗?

1 个答案:

答案 0 :(得分:2)

如果您开始传递处理程序函数向下,您将反对自然的事件流,因为它们通过DOM冒泡向上

相反,使用侦听器将组件包装在处理元素中,并使用事件冒泡。

(Component) => class TrackMouseOver extends React.Component {
  handleMouseOver(e) {
    e.target        // is the element that triggered the event
    e.currentTarget // is the element this handler is attached to
  }

  render() {
    return (
      <div onMouseOver={this.handleMouseOver}>
        <Component {...this.props} />
      </div>
    );
  }
};

当您点击新div内的其中一个元素时,该事件的生命周期为两部分。

捕获

浏览器确定事件发生在哪个顶级元素,然后该元素的哪个子元素依此类推,直到事件最终结束于没有子元素的元素 - 目标。

此序列不会触发任何事件侦听器(除非它们设置了useCapture标志),它只是标识事件的路径。

鼓泡

现在已经到达事件的目标元素,事件会将捕获的路径返回到DOM的根目录,并在事件发生时触发事件侦听器。

这是附加到body元素的事件处理程序始终触发*的原因,无论事件发生在哪个元素上。 body是所有元素的共同祖先。

在您的情况下,您可以利用div中任何元素的事件最终会冒泡到此事件处理程序的事实。

您可以使用event.target确定事件来自哪个元素。

*如果某个后代元素上的事件处理程序调用{​​{1}}或event.preventDefault,则不会触发事件处理程序。