反应-操纵DOM还是使用状态?

时间:2019-05-27 21:26:18

标签: reactjs

这更多是一个“理论”问题,经常在不同情况和用例中使我困惑,我将举一个简单的例子来演示它。

假设我有10个按钮的列表。 Everrytime我单击一个按钮,在单击的按钮上方会出现一个浮动菜单-在任何给定时间内只有一个菜单可见。 假设我无法在按钮组件中呈现此浮动菜单,而只能在按钮父级中呈现(这意味着该菜单与那些按钮同级)。

我有2种可能的选择:

  1. 保持最后单击的按钮的x,y位置,并在此给定位置呈现菜单
  2. 渲染菜单一次,然后使用“ ref”直接重新定位菜单

一方面,第一种方法看起来更像是“反应灵”。另一方面,我能想到的可能实现很丑陋(捕获单击的项目位置并将其保存到触发防御者的状态),此外,我不确定重新渲染整个容器是因为我需要移动一小部分。

第二种方法直接使用引用接触DOM。尽管可能,但是进行DOM操作有时会让我感到难受。

有没有更好的方法?哪两个更有意义?

任何建议或想法将不胜感激! 谢谢

1 个答案:

答案 0 :(得分:2)

React使用所谓的虚拟DOM,它是DOM的表示形式,它位于真实浏览器DOM的顶部。每当您更新状态或用户执行操作时,虚拟DOM就会比较并检查与真实DOM的更改,然后相应地更新UI。

因此,如果某些DOM元素(如a)在更改之间没有区别,则不会重新呈现,只有已更改的DOM元素才会重新呈现。并且,如果更改了DOM元素上的属性,则只会更新该属性,并且不会重新呈现DOM元素。

<div color="blue" /> 

<div color="red" /> 

不会破坏并重新创建整个元素,仅会更改属性。

但是,如果主机树中的元素与整个主机树不同,则将销毁并重新创建。

<div />

<p>

这称为对帐 https://reactjs.org/docs/reconciliation.html

因此,使用refs绝对更像是一种骇人听闻的解决方案,因为它更像是逃脱舱门并直接操纵DOM。

我肯定会坚持使用选项1,我认为您所描述的用例有一个优雅的解决方案,其中涉及在componentDidMount中添加一个click事件监听器,并以此方式跟踪点击位置。

没有代码也很难说,但是由于您的按钮将是相同的,因此仅菜单将不会重新呈现它们。

建议进一步阅读 https://overreacted.io/react-as-a-ui-runtime/