首页 > web前端 > js教程 > 正文

使用虚拟 DOM 和引用进行高效 DOM 操作

WBOY
发布: 2024-07-29 17:10:06
原创
464 人浏览过

Efficient DOM Manipulation with the Virtual DOM and Refs
快速响应的网站的秘密
有没有想过为什么您最喜欢的网站如此快速且响应迅速?这一切都归结为他们如何处理 DOM 操作。文档对象模型 (DOM) 将您的网页表示为结构化树。传统上,我们使用 getElementById 或 removeChild 等 JavaScript 方法来进行更改。但随着网站变得越来越复杂,这些方法可能会减慢速度。 React 登场了,它的虚拟 DOM 改变了游戏规则。

传统 DOM 操作的挑战
将 DOM 视为一棵拥有大量分支的大树。每当您想要更改某些内容(例如更新十个列表中的第一项)时,您最终都会摇动整棵树。这可能会减慢速度,尤其是当网页变得更加复杂时。分支(元素)越多,保持一切顺利运行就越困难。

React 的解决方案:虚拟 DOM
React 通过 Virtual DOM(HTML DOM 的轻量级副本)解决了这个问题。更改首先应用于虚拟 DOM,然后 React 有效地更新真实 DOM 以反映这些更改。这个过程称为“协调”,可确保仅更新 DOM 的必要部分,从而显着提高性能。

虚拟 DOM 的工作原理
当您在 React 中渲染 JSX 元素时,整个虚拟 DOM 都会更新。虽然这听起来效率很低,但它比直接操作真实 DOM 更快。原因如下:React 在进行任何更新之前创建虚拟 DOM 的副本。然后,它使用称为 Diffing 的过程将更新后的 Virtual DOM 与此副本进行比较。这种比较可以识别已更改的特定元素,React 仅更新真实 DOM 中的那些元素。

底层:React 的 Diffing 算法
React 的 Diffing 算法是其高效 DOM 更新背后的秘密武器。该算法比较虚拟 DOM 的两个版本,并应用同步它们所需的最小更改集。
如果两棵树的根元素类型不同,React 将重建整个树。例如,将

更改为 a 将导致 React 拆除并从头开始重建树。
<div>
  <Tree/>
</div>
<span>
  <Tree/>
</span>
登录后复制

由于根元素(div 和 span)不同,React 将重建整个树。

相同的元素类型

<span id="span1" />
<span id="span2" />
登录后复制

这里,React 只会更新 id 属性,元素的其余部分保持不变。

比较子元素

React 还优化了子元素的更新。考虑这些列表:

<ul>
  <li>Child1</li>
  <li>Child2</li>
</ul>
登录后复制
<ul>
  <li>Child1</li>
  <li>Child2</li>
  <li>Child3</li>
</ul>
登录后复制

React 将 Child3 视为新的并进行相应更新。但是,如果在开头添加新元素,React 可能会重建整个列表。这就是钥匙发挥作用的地方。
按键在优化更新中的作用

键帮助 React 跟踪哪些元素已更改、添加或删除。它们在兄弟姐妹中应该是唯一的,并且在渲染中应该是稳定的。

<ul>
  <li key="101">Child1</li>
  <li key="102">Child2</li>
</ul>
登录后复制
<ul>
  <li key="100">Child3</li>
  <li key="101">Child1</li>
  <li key="102">Child2</li>
</ul>
登录后复制

在此示例中,React 知道 Child3 是新的,并有效地更新列表而不重建它。

使用 Ref 操作 DOM
虽然 React 使用 Virtual DOM 优化 DOM 更新,但在某些情况下需要直接操作 DOM 元素,例如聚焦输入、滚动到特定元素或测量元素的尺寸。 React 为此提供了 useRef Hook。通过创建 ref 并通过 ref 属性将其附加到 DOM 元素,您可以直接访问 DOM 节点。 useRef Hook 返回一个具有当前属性的对象,该属性最初为 null,但在渲染后会被分配 DOM 节点。这允许您直接在元素上调用本机 DOM 方法,从而增强对特定交互的控制。例如,您可以使用 myRef.current.scrollIntoView() 将元素滚动到视图中。

示例:变色 Div
让我们创建一个有趣的示例来看看它的实际效果。我们将制作一个当您单击按钮时改变颜色的 div。我们将使用基于类的组件和 ref 来直接操作 div 的样式。

<div id="root"></div>
登录后复制
const root = ReactDOM.createRoot(document.getElementById('root'));

class ColorChanger extends React.Component {
  constructor(props) {
    super(props);
    this.divRef = React.createRef();
    this.colors = ['#FFCDD2', '#C8E6C9', '#BBDEFB', '#FFF9C4', '#D1C4E9'];
    this.state = { colorIndex: 0 };
    this.changeColor = this.changeColor.bind(this);
  }

  changeColor() {
    const nextColorIndex = (this.state.colorIndex + 1) % this.colors.length;
    this.setState({ colorIndex: nextColorIndex });
    this.divRef.current.style.backgroundColor = this.colors[nextColorIndex];
  }

  render() {
    return (
      <div className="container">
        <div
          ref={this.divRef}
          className="color-box"
          style={{
            backgroundColor: this.colors[this.state.colorIndex],
          }}
        ></div>
        <button onClick={this.changeColor}>Change Color</button>
      </div>
    );
  }
}

root.render(<ColorChanger />);
登录后复制

说明

创建根:React 应用程序的根是使用 ReactDOM.createRoot(document.getElementById('root')) 创建的。
ColorChanger 组件:
构造函数:使用 React.createRef() 初始化 ref,设置颜色数组,并初始化状态以跟踪颜色索引。
changeColor 方法:计算下一个颜色索引,更新状态,并通过直接操作 DOM 来更改 div 的背景颜色。
渲染方法:渲染div和按钮,将ref附加到div并将按钮的onClick处理程序设置为changeColor。
渲染组件:ColorChanger 组件被渲染到根元素中。
结论
React 的 Virtual DOM 改变了 Web 开发的游戏规则,使我们的应用程序更加高效、响应更快。通过利用虚拟 DOM,React 确保仅更新 DOM 的必要部分,从而提高性能。了解 React 的 Diffing 算法和键的工作原理可以帮助您创建更流畅、更快的 React 应用程序。当你需要精确控制时,React 的 refs 可以帮助你直接与 DOM 交互。拥抱 Virtual DOM 的强大功能,将您的 Web 开发技能提升到新的水平!

以上是使用虚拟 DOM 和引用进行高效 DOM 操作的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板