Coursera 笔记

Module 02 · Understanding Function Components with Array and DOM Manipulation函数组件、数组与 DOM 操作

Virtual DOM Manipulation in ReactReact 中的虚拟 DOM 工作原理

Coursera ↗

欢迎观看关于 虚拟 DOM 在 React 中如何工作的 视频!观看完本视频后,你将能够:

  • 定义文档对象模型 (DOM) 及其组件
  • 描述虚拟 DOM 在 React 中的工作原理
  • 列出虚拟 DOM 在 React 中的优势
  • 比较常规 DOM 和虚拟 DOM

什么是 DOM?

文档对象模型(DOM)是一个用于表示网页和文档的接口,它将 HTML 结构表示为一个树形结构。每个节点代表文档中的一个部分,如元素、属性和文本。

DOM 的组件

  • 节点 (Nodes):是 DOM 的基本单位,包括元素、文本、属性等。
  • 元素 (Elements):HTML 文档的基本构建块,表示文档的内容。
  • 属性 (Attributes):提供有关元素的附加信息,可以指定元素的属性、样式或行为。
  • 事件 (Events):允许 JavaScript 代码响应用户交互或文档中的其他操作。

DOM 通过树形结构来表示文档,其中包含不同类型的节点,如元素节点、文本节点和属性节点等。


虚拟 DOM 的工作原理

虚拟 DOM 是 React 等框架中用于优化 Web 应用性能的概念。它是实际 DOM 的一种抽象,保存在内存中,并通过 React 的协调 (Reconciliation) 过程与真实 DOM 保持同步。

虚拟 DOM 的工作流程

  1. 初次渲染:在 React 组件首次渲染时,会创建一个虚拟 DOM 模型。
  2. 状态更新:当组件的状态 (state) 或属性 (props) 发生变化时,React 会创建一个新的虚拟 DOM 表示。
  3. 差异算法 (Diffing Algorithm):React 使用差异算法对比新虚拟 DOM 和上一个虚拟 DOM,找出需要更新到真实 DOM 的最小变化。
  4. 批量更新 (Batching):React 使用批量更新技术,将所有变化分组并高效地作为补丁 (patch) 应用到真实 DOM,从而减少不必要的重新渲染和 DOM 操作。


虚拟 DOM 在 React 中的优势

虚拟 DOM 在 React 中有多个优势:

  • 提高性能:减少 DOM 更新的频率,提高 Web 应用速度。
  • 简化开发:开发者可以专注于声明式编程,而不必担心 DOM 操作的复杂性。
  • 跨平台兼容性:虚拟 DOM 的抽象使得 React 组件可以高效地在不同平台(如 Web 浏览器和移动设备)上渲染。
  • 状态管理:与虚拟 DOM 配合,React 能有效响应应用状态的变化,进行高效的更新和重新渲染。
  • 调试和测试:开发者可以在开发过程中检查虚拟 DOM 版本,简化调试和测试。


虚拟 DOM 允许开发者创建可重用的组件,这些组件可以高效地组合和更新。React 的声明式语法使开发者能够描述预期的 UI 状态,而 React 则会相应地更新虚拟 DOM 并渲染组件。此外,虚拟 DOM 还支持 React 的服务器端渲染,从而提升页面初始加载性能,并优化 Web 应用的搜索引擎优化(SEO)。


虚拟 DOM 与常规 DOM 的比较

特性 常规 DOM 虚拟 DOM
加载过程 浏览器解析 HTML 内容并生成 DOM 树 React 在内存中构建虚拟 DOM 树
更新过程 直接操作真实 DOM,进行重新渲染和重排 React 通过虚拟 DOM 计算差异,只更新需要改变的部分
性能 在复杂页面中,操作 DOM 可能会很昂贵 只更新必要的部分,提高性能
内存消耗 需要消耗更多内存用于真实 DOM 操作 由于虚拟 DOM 保存在内存中,内存消耗较少

常规 DOM 更新过程

  1. 浏览器加载网页,解析 HTML 内容并生成 DOM 树。
  2. 解析 HTML 标记,生成 DOM 节点,并在浏览器中显示内容。
  3. 渲染复杂网页时,DOM 树庞大且频繁更新会导致性能开销。

虚拟 DOM 更新过程

  1. React 在内存中创建虚拟 DOM 树,初始状态基于组件的 state 和 props。
  2. 当状态或属性更新时,React 比较当前虚拟 DOM 和更新后的虚拟 DOM,找出最小的差异。
  3. 只将这些最小的差异应用到真实 DOM,减少不必要的 DOM 操作,提高渲染效率。

React 中的虚拟 DOM 示例

创建一个简单的 React 示例,包含两个子组件:一个父组件 App.jsx,一个第一个子组件和一个第二个子组件。

  • 父组件:维护一个列表的状态。
  • 第一个子组件:渲染一个包含更新按钮的列表。
  • 第二个子组件:仅显示与自身相关的信息。

代码示例

// 父组件
function App() {
  const [items, setItems] = useState(['item1', 'item2', 'item3']);

  const updateItem = () => {
    const newItems = [...items];
    newItems[0] = 'Updated Item';
    setItems(newItems);
  };

  return (
    <div>
      <FirstChild items={items} updateItem={updateItem} />
      <SecondChild />
    </div>
  );
}

// 第一个子组件
function FirstChild({ items, updateItem }) {
  return (
    <div>
      <ul>
        {items.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
      <button onClick={updateItem}>Update Item</button>
    </div>
  );
}

// 第二个子组件
function SecondChild() {
  return <div>Second Child Component</div>;
}


执行效果

  • 初次加载时,所有组件都会渲染。
  • 当点击更新按钮时,只有第一个子组件会重新渲染,父组件和第二个子组件不会改变。

控制台日志

  • 初次加载:所有组件渲染。
  • 更新后:只有第一个子组件重新渲染。

React 的虚拟 DOM 比较更新后的组件和之前的虚拟 DOM,确定只有第一个子组件的状态发生了变化,因此只更新该组件的部分 DOM,而不会重新渲染整个列表。


总结

在本视频中,你学习了以下内容:

  • DOM:允许程序动态地访问和操作网页文档的内容、结构和样式。
  • 虚拟 DOM:是实际 DOM 的内存中的抽象表示,通过 React 的协调过程保持与真实 DOM 的同步。
  • 虚拟 DOM 优势:
    • 只更新必要的部分,提高了性能。
    • 通过减少不必要的 DOM 操作,提升了 Web 应用的速度。
    • 提供了组件的重用性和简洁的声明式更新。

通过虚拟 DOM,React 确保只更新必要的部分,从而显著提高了应用性能,特别是在只需要更新特定组件或元素的场景下。


🎉 虚拟 DOM 带来了更高效、更流畅的 React 开发体验! 🚀