【问题标题】:Reactjs: Event delegation similar to jQuery `on()`?Reactjs:类似于 jQuery `on()` 的事件委托?
【发布时间】:2017-03-07 08:55:34
【问题描述】:

我是 React.js 的新手。我创建了一个列表组件,其中经常添加/删除项目。每个项目都应该有一个点击和/或悬停事件。

我想以我们在 jQuery 中使用on(event, selector, data, handler) 方法的类似方式进行事件委托,这样我就可以在列表父元素上绑定/取消绑定事件,而不必担心添加/删除每个子项的事件绑定/取消绑定.

【问题讨论】:

  • 我相信 React 会自动委托事件(例如,如果您在每个项目上放置 onClick,React 实际上不会这样做),但我不能(不再)在反应文档...
  • @T.J.Crowder 我相信您所指的是合成事件处理程序。 facebook.github.io/react/docs/events.html
  • @spirift:这是其中的一部分(但它们也用于跨浏览器规范化,如 jQuery 的$.Event),但文档过去专门指出处理程序已被委派。但在文档中搜索 delegationdelegate 不再出现结果。
  • @T.J.Crowder 我认为你是对的,<button onClick={(e) => {console.log(e.nativeEvent.currentTarget)}}/>` 将记录 document 元素

标签: javascript reactjs event-handling event-delegation


【解决方案1】:

正如文档所说,

使用 React 元素处理事件与处理 DOM 元素的事件非常相似。 React 事件使用 camelCase 命名,而不是小写。使用 JSX,您将函数作为事件处理程序传递,而不是字符串。 (https://facebook.github.io/react/docs/handling-events.html)

假设您 use a class as the React component,如果您希望每个项目都有点击和/或悬停事件,您可以在您的类的 render() 方法中输入这些:

<a onClick={this.onClickEventHandler}
   onMouseEnter={this.onMouseEnterEventHandler}
   onMouseLeave={this.onMouseLeaveEventHandler}>
sample item
</a>

之后,您可以在您的类中声明这些事件处理程序(onClickEventHandler、onMouseEnterEventHandler 和 onMouseLeaveEventHandler)并告诉他们要做什么。

最后,您需要在类构造函数中绑定事件处理程序:

constructor(props){
  super(props);
  this.onClickEventHandler = this.onClickEventHandler.bind(this);
  this.onMouseEnterEventHandler= this.onMouseEnterEventHandler.bind(this);
  this.onMouseLeaveEventHandler= this.onMouseLeaveEventHandler.bind(this);
}

看到这个Plunker for the example of event handling in React

您可以稍后通过实现“lifting state up”的概念在父组件中使用这些事件。这样,您可以通过触发子组件中的事件在父组件中运行方法。看到这个Plunker for the example of lifting state up in React

【讨论】:

    【解决方案2】:

    在 React 中,我们通常不使用选择器来绑定/取消绑定事件,而是直接将合成事件处理程序添加到子级。在像列表这样的组件中,每当更新列表项(添加/删除/编辑等)时,都会重新呈现父项。所以,在你的渲染函数中,你可能会做这样的事情:

    render(){
    
      // your list component will either keep the items in its state, 
      // or receive them as props from its parent or from a store like redux.
    
      const { listItems } = this.props;
      
      // then, adding your event handlers is simply a matter of mapping over 
      // your list items and rendering your desired jsx from each item:
    
      const renderedItems = () => {
        return listItems.map(item => {
          return (
            <div 
              onClick={ this.handleClick(item) }
              onMouseEnter={ this.handleMouseEnter(item) }>
              { item.text }
            </div> 
          );
        });
      };
      
      // then it's just a matter of calling your rendered items 
      // in render's return:
      
      return(
        <div>
          { renderedItems() }
        </div>
      )
    }

    请注意,在使用 React 的 createClass() 函数的组件中不需要绑定,因为 React 会自动处理绑定。

    【讨论】:

    • 假设我有一个通用的项目组件,可以在不同的列表组件中作为子组件重用,其中相同的项目组件可能具有不同的行为(对于用户交互:单击或其他事件)为每个父组件。在这种情况下,合成事件处理程序将不起作用。
    • 在你的例子中,我猜this.handleClick(item)this.handleMouseEnter(item) 会执行这些方法而不是绑定它们。
    • @Vikram - 在这种情况下,您可以让列表组件将其处理程序传递给子组件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多