【问题标题】:Handling event using custom data attributes or binding data to the handler?使用自定义数据属性处理事件还是将数据绑定到处理程序?
【发布时间】:2016-06-03 09:55:41
【问题描述】:

我正在使用 React,但这不一定是 React 特定的问题。

在事件处理程序中获取自定义数据属性是否有主要区别

<MyElement greeting="hello" farewell="goodbye" />

//MyElement component
handleClick(event) {    
  console.log(event.currentTarget.dataset.myData);
}
...
<li data-my-data={this.props.greeting} onClick={this.handleClick}>Click Greeting</li>
<li data-my-data={this.props.farewell} onClick={this.handleClick}>Click Farewell</li>

并将值绑定到事件处理程序

<MyElement greeting="hello" farewell="goodbye" />

//MyElement component
handleClick(myData) {
  console.log(myData);
}
...
<li onClick={this.handleClick.bind(this, this.props.greeting)}>Click Greeting</li>
<li onClick={this.handleClick.bind(this, this.props.farewell)}>Click Farewell</li>

这只是个人喜好问题,还是每个都有实际的利弊?

【问题讨论】:

  • 第一个选项是安全的。没有人有权修改它。但是第二个选项人们可能会错误地更改值。

标签: javascript html reactjs


【解决方案1】:

简短回答:这是个人喜好问题,每种解决方案都有优缺点。 恕我直言,选项 1 是围绕 React 设计原则的捷径,以后会给您带来很多麻烦。

PRO 选项 1:将数据“存储”在 DOM 数据集中:

  • 在您的组件中减少繁琐的绑定内容
  • 数据集也可以从反应组件外部访问;其他组件/代码可以直接读取/更新数据集

PRO 选项 2:将数据“存储”在 react javascript 组件中

  • 如果传递的目标是正确的 DOM 节点,则无需担心。 (event.currentTarget 采用带有事件监听器的第一个较高级组件,event.target 采用点击元素)
  • 数据集只能从 React 组件内部访问,保持代码更简洁

我个人的偏好是选项 2:它迫使你坚持 react 数据流和设计原则,并将所有相关代码保存在 javascript react 组件内的同一位置。

这可以保护您免于走下地狱之路(在大型项目和大型团队中尤其普遍):

  • 新要求:某些远程组件需要访问数据集
  • react 组件树的适当重新设计是乏味的:您可能需要将数据集的管理移至更高的组件以提供对数据集的访问权限,这意味着对 react 组件树的修订。
  • 但有一个捷径可用:远程组件也可以直接从 DOM 读取 - 所以选择快速而肮脏的解决方案
  • 新要求:原组件需要更新
  • 现在无法找出哪些其他组件实际读取/依赖数据集,因此您的代码实际上变得难以管理。

【讨论】:

  • 也许我不明白你在说什么,但 React 仍然可以在第一个选项中管理数据。自定义数据属性的值也可以是花括号中的变量(例如,道具、状态等)。你介意给我一个例子,说明event.currentTarget 何时无法按预期工作吗?你的意思是event.target吗?
  • 更新了我的答案以进一步解释:数据不存储在组件中,而是存储在 DOM 中。当组件获得更多结构时,您的event.target(或event.currentTarget)可能无法指向正确的 DOM 项,并且无法访问数据(很难调试)。最大的问题可能是您创建了一个后门来从组件外部访问数据,这为调试噩梦开辟了道路。
  • 我刚刚更新了我的问题,试图展示我对 React 管理数据的看法。我知道在使用数据属性时这些值最终会出现在 DOM 中,但是当道具更改等时元素仍会被渲染。我明白你在说什么 event.target,这就是我使用 @987654328 的原因@ 因此,当单击 &lt;li&gt; 的子项时,将使用正确的数据集
  • 重写了我的答案。两者都可以,但 2 使您的代码更容易随着应用程序的增长而维护。
【解决方案2】:

这样做,使用 ES6 箭头函数:

<li onClick={()=>this.handleClick(this.props.greeting)}>Click Greeting</li>

这比bind 更简洁、更高效,并且比选项 (1) 需要的代码少得多。

唯一(潜在的)缺点是,在这种情况下,您每次在 render() 期间都会创建新的函数对象。只有当您将回调传递给依赖于 shouldComponentUpdate() 优化的自定义组件时,这才是问题所在。在这种情况下,选项 (1) 应该是最好的,因为您应该避免动态创建的闭包。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 2015-01-22
    相关资源
    最近更新 更多