当前位置: 首页 > news >正文

DOM中的diff算法详解

经典面试题:

1.react/vue中的key有什么作用?key的内部原理是什么?

2.为什么遍历列表时,key最好不要用index?

看完以下内容,轻松解决你对diff算法的认识以及以上两个常问问题。

虚拟DOM中key的作用:

1.当数据状态发生变化时,react/vue会根据新数据生成新的虚拟dom,随后会进行新旧dom的比较,比较规则如下:

①旧虚拟dom中找到了新虚拟dom相同的key:

(1)若虚拟dom中内容没变,直接使用之前的真实dom

(2)若虚拟dom中内容变了,则生成新的真实dom,并替换掉页面中之前的真实dom

②旧虚拟dom中未找到新虚拟dom相同的key:

(1)根据数据创建新的真实的dom,并渲染到页面

2.用index作为key可能会引发的问题

①若数据进行:逆序添加、逆序删除等破坏顺序的操作,此时会产生没有必要的真实的dom更新,虽然界面效果没什么问题,但效率低

②如果结构中还包含输入类的dom,会产生错误dom更新,界面会发生问题

③注意:如果不存在数据的逆序添加,逆序删除等破坏顺序性操作,仅用于渲染列表到页面,一般是没有问题的

3.开发中如何选择key值

①最好使用每条数据的唯一标识作为key,如id,身份证号等

②如果确定只是简单的展示数据,也可以用index

import React, { Component } from 'react'

export default class ClassHanshu extends Component {
  constructor() {
    super()
    this.state = {
      persons: [
        { id: 1, name: "张三", age: 18 },
        { id: 2, name: "张四", age: 19 },
      ]
    }
  }
  // 用index索引作为key时:
  // 初始数据: 
  // { id: 1, name: "张三", age: 18 },
  // { id: 2, name: "张四", age: 19 },
  // 初始虚拟dom
  // <li key=0>张三,18</li>
  // <li key=1>张四,19</li>
  // 页面更新后数据
  // { id: 3, name: "张五", age: 20 },
  // { id: 1, name: "张三", age: 18 },
  // { id: 2, name: "张四", age: 19 },
  // 页面更新后虚拟dom
  // <li key=0>张五,20</li>
  // <li key=1>张三,18</li>
  // <li key=2>张四,19</li>
  //  此时新旧虚拟dom根据key进行对比发现里面的内容变了,便替换掉了页面中之前真实的dom,而这意味着两条重复的数据没有重复利用,当数据庞大时效率可想而知
  add() {
    const { persons } = this.state
    const p = { id: persons.length + 1, name: "张五", age: 20 }
    this.setState({
      persons: [p, ...persons]
    })
  }
  render() {
    return (
      <div>
        <button onClick={() => { this.add() }}>点击添加一个张五</button>
        <ul>
          {
            this.state.persons.map((personObj, index) => {
              return <li key={index}>{personObj.name},{personObj.age}</li>
            })
          }
        </ul>
      </div>
    )
  }
}
import React, { Component } from 'react'

export default class ClassHanshu extends Component {
  constructor() {
    super()
    this.state = {
      persons: [
        { id: 1, name: "张三", age: 18 },
        { id: 1, name: "张四", age: 19 },
      ]
    }
  }
  // 用id作为key时:
  // 初始数据: 
  // { id: 1, name: "张三", age: 18 },
  // { id: 2, name: "张四", age: 19 },
  // 初始虚拟dom
  // <li key=1>张三,18</li>
  // <li key=2>张四,19</li>
  // 页面更新后数据
  // { id: 3, name: "张五", age: 20 },
  // { id: 1, name: "张三", age: 18 },
  // { id: 2, name: "张四", age: 19 },
  // 页面更新后虚拟dom
  // <li key=3>张五,20</li>
  // <li key=1>张三,18</li>
  // <li key=2>张四,19</li>
  //  此时新旧虚拟dom根据key进行对比发现没有的便在页面渲染,有的并且内容一样的便用之前真实的dom
  add() {
    const { persons } = this.state
    const p = { id: persons.length + 1, name: "张五", age: 20 }
    this.setState({
      persons: [p, ...persons]
    })
  }
  render() {
    return (
      <div>
        <button onClick={() => { this.add() }}>点击添加一个张五</button>
        <ul>
          {
            this.state.persons.map((personObj) => {
              return <li key={personObj.id}>{personObj.name},{personObj.age}</li>
            })
          }
        </ul>
      </div>
    )
  }
}

相关文章:

  • 前端网站动态主题色解决方案
  • 用DevExpress实现基于HTMLCSS的桌面应用程序的UI(一)
  • Android OpenGL ES 3.0 PBO像素缓冲区对象
  • 腾讯T4级架构师用21个项目带你吃透379页深度学习TensorFlow实践pdf
  • Eureka服务注册发现原理
  • RK3399平台开发系列讲解(中断篇)中断控制器驱动初始化
  • 【Redis】Redis的持久化
  • LibreOJ_10010
  • 数据增强
  • 一文搞懂堆外内存(模拟内存泄漏)
  • 还在调API写所谓的AI“女友”,唠了唠了,教你基于python咱们“new”一个(深度学习)
  • Win7纯净版系统镜像64位介绍
  • Kali系统MSF模块暴力破解MySQL弱口令漏洞
  • [附源码]java毕业设计疫情环境下的酒店管理系统
  • kafka配置外网访问
  • java每一练(3)
  • Java学习----前端4
  • ABAP中 delete 语句的使用
  • cesium火箭发射,模型控制,模型动画,模型移动
  • http请求走私漏洞原理,利用,检测,防护
  • Springboot魅力乡村管理系统srb4s计算机毕业设计-课程设计-期末作业-毕设程序代做
  • 【星球】【slam】 研讨会(5)VINS:Mono+Fusion 重点提炼
  • 机器学习笔记之受限玻尔兹曼机(三)推断任务
  • 机器学习之过拟合和欠拟合
  • 【Linux网络编程】服务端编程初体验
  • 《人类简史》笔记四—— 想象构建的秩序
  • 燃煤_太康锅炉厂家
  • 锅炉烟气脱硫除尘器_燃煤锅炉
  • 卧式燃油锅炉_燃油锅炉 燃煤锅炉