优化 React:理解 DOM Diffing 算法及关键的 key 属性

优化 React:理解 DOM Diffing 算法及关键的 key 属性

DOM 的 Diffing 算法和 Key 的作用

在 React 中,DOM 的 Diffing(差异比较)算法是一种优化手段,用于确定虚拟 DOM 树与实际 DOM 树之间的差异,并仅更新必要的部分,以提高性能。

DOM Diffing 算法的基本原理

React 在进行 Virtual DOM 更新时,会通过 Diffing 算法对新旧 Virtual DOM 进行比较,找出变化并仅更新这部分差异,而不是整个重新渲染。这个算法的基本原理可以概括为:

  1. Tree Reconciliation(树协调): 对比新旧树的结构,找出变化的部分。

  2. Component Reconciliation(组件协调): 对比同一层级的组件,找出需要更新的组件。

Key 的作用

在 React 中,key 是用来帮助 React 识别列表中的每个元素的唯一标识。在下面代码中,使用了 key 属性来标识每个列表项:

jsx 复制代码
{this.state.persons.map(p => <li key={p.id}>姓名: {p.name}  年龄:{p.age}</li>)}

这里的 p.id 就是每个列表项的唯一标识。Key 的作用主要有以下几点:

  1. 唯一性: Key 用于标识每个列表项,确保在列表中的每个元素都有一个唯一的标识。这有助于 React 更准确地识别每个元素,提高 Diffing 算法的效率。

  2. 稳定性: Key 保持稳定,确保相同位置的元素在更新时能够正确匹配,而不是混淆顺序。

用 id 和 index 为 Key 的区别

在代码中,使用了 id 作为每个列表项的 key:

jsx 复制代码
{this.state.persons.map(p => <li key={p.id}>姓名: {p.name}  年龄:{p.age}</li>)}

使用 id 作为 Key 通常是比较好的做法,因为 id 具有唯一性,它能够确保每个元素在列表中都有一个独特的标识。

相比之下,使用 index 作为 Key 有一些潜在的问题。如果列表中的元素发生变化,插入或删除元素,index 可能会发生变化,导致 React 难以准确匹配新旧元素,从而降低 Diffing 算法的效率。

完整代码

jsx 复制代码
class Person extends React.Component {
  state = {
    persons: [
      { id: 1, name: 'Judith', age: 19 },
      { id: 2, name: "Jane", age: 18 },
    ],
  }

  add = () => {
    const { persons } = this.state;
    this.setState({
      persons: [
        { id: persons.length + 1, name: '张三', age: 21 },
        ...persons
      ],
    });
  }

  render() {
    return (
      <div>
        <button onClick={this.add}>添加一个张三</button>
        <ul>
          {this.state.persons.map(p => <li key={p.id}>姓名: {p.name}  年龄:{p.age}</li>)}
        </ul>
      </div>
    );
  }
}

总体而言,尽量使用具有稳定唯一性的标识作为 Key,以确保 React 能够正确而高效地进行差异比较。

参考

相关推荐
用户298698530142 天前
React 前端将 Excel 工作表导出为图片的技术实践
javascript·react.js·excel
終不似少年遊*3 天前
【安全业务Agent】从场景到编排
python·react.js·ai·langchain·agent·安全架构·工作流
JavaPub-rodert4 天前
从零搭建通用管理后台:ShiyuAdmin 的 Go、React 与 RBAC 实践
开发语言·react.js·golang
Highcharts.js4 天前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
JudithHuang4 天前
React 嵌套路由与布局
前端·react.js·arcgis·react·react router
前端小D4 天前
React Native项目开发(iOS侧为例)
javascript·react native·react.js
志尊宝5 天前
AI原生前端开发(042):AI辅助的路由设计与优化
javascript·react.js·ai-native
znsoft6 天前
MaClaw(码卡龙)技术拆解:一个 Go + React 的可自进化智能体平台
开发语言·react.js·golang
濮水大叔6 天前
React/Next.js 生态里,有没有 CabloyJS 这样的全栈框架?
react.js·全栈·next.js
前端小D6 天前
React Native Android 项目搭建
android·react native·react.js