后端程序员入门react笔记——react的diff算法(三)

这篇具有很好参考价值的文章主要介绍了后端程序员入门react笔记——react的diff算法(三)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

diffing算法

虚拟dom

我们知道,react里面操作的都是虚拟dom,最后经过render渲染为真正的dom,那么为什么要提出虚拟dom这个概念呢?其实就是将逻辑和视图区分开,react的虚拟dom,就相当于mvc的c,将数据逻辑和真正的dom区分开,我们知道,对于前端来说dom操作是非常昂贵的,性能消耗最大的就是dom操作。而virtual dom减少了对dom的操作,,不仅避免了资源浪费,而且页面的构建也得到了很大的提升。

为什么要diff

前面我们说了,应避免过多的操作dom,那么diff就是解决了这种问题。我们知道,react在状态发生变化的时候,会批量更新dom,生成新的UI,但是难道state的某一个值发生变化就要导致整个dom重新渲染吗?这明显是不科学的,为了解决这种问题,react提出了diff算法,通过对比新旧的两个虚拟dom树来检测那些dom是真的需要重新如安然,哪些dom是没有变化的。

diff算法

传统的diff算法是通过循环递归的方式对节点一次进行对比,需要O(n ^3)的时间复杂度。为什么?我们从最简单的说,把一棵树转换为另外一棵树,其实就是把一颗n个节点的树挨个儿去另一棵n个节点的树中查找,整个过程是n*n,那么如果发现有不同的地方,我们就需要需改,对一棵树的增删改的算法复杂度是n,那么整个过程就是n*n*n
后端程序员入门react笔记——react的diff算法(三),react.js,笔记,算法
react将这种对比策略做了一个优化,将复杂度降到了O(n),那么react是怎么实现的呢?react的diff会预设三个限制

  • 只进行同层级比较
  • 新旧节点的type不同,直接删除旧节点,创建新节点,比如组件不同,元素的类型不同,原来是ul,里面是li,后来改成了div+p,这个时候就会删除旧dom,创建新的dom.
  • 通过key来复用节点

在上面三个限制的基础上,对tree,conponent,element的处理方式又做了优化

  • dom节点不一致直接删除旧节点,创建新节点
  • 组件类型不一致直接删除组件下所有节点,创建新节点
  • 同一层的dom元素,以每个元素对应的key为标识,提供三种操作方式,删除新建和移动
    后端程序员入门react笔记——react的diff算法(三),react.js,笔记,算法

diff的最小颗粒度

diff的最小颗粒度是标签,我们举例看一下

class Hello extends React.Component {
   state={
       time:new Date()
   }
   componentDidMount(){
       this.timer=setInterval(()=>{
           this.setState({
               time:new Date()
           })
       },5000)
   }
   render() {
       console.log("i am render")
       return (
           <ul>
               <li>备注:<input type="text"/></li>
               <li><span>{this.state.time.toTimeString()}</span></li>
           </ul>
       )
   }
}

我们看到,每隔5秒,span标签就会从新刷新一次,而其他元素没有变化
后端程序员入门react笔记——react的diff算法(三),react.js,笔记,算法

key

前面我们说了,同一层级的元素如果发生了变化,可以删除 插入和移动,前提是必须有key作为标识,如果没有key,比如下面代码

class Hello extends React.Component {
    state = {
        heros: [
            {
                id: 1,
                name: "张三"
            },
            {
                id: 2,
                name: "李四"
            }
        ]
    }
    render() {
        console.log("i am render")
        return (
            <ul>
                {this.state.heros.map((hero,index)=>{
                    return <li>{hero.name}</li>
                })}
            </ul>
        )
    }
}

这个时候浏览器提示了一个warm ,意思是每一个child都应该有唯一key。
后端程序员入门react笔记——react的diff算法(三),react.js,笔记,算法
那么这个key应该怎么选取呢

  • 最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
  • 如果确定只是简单的展示数据,用index也是可以的。 但是不推荐。
    为什么不推荐index作为key,官方文档说,如果列表项目的顺序可能会变化,我们不建议使用索引来用作 key 值,因为这样做会导致性能变差,还可能引起组件状态的问题。

我们来举个例子对比一下,再分析问题所在。这段代码里,我点击添加按钮的时候,改变了原来数组对象的顺序,在数组的前头添加了一个对象,我们点击看一下效果

class Hello extends React.Component {
    state = {
        heros: [
            {
                id: 1,
                name: "张三"
            },
            {
                id: 2,
                name: "李四"
            }
        ]
    }
    addHero=()=>{
        this.setState({
            heros: [
                {
                    id: 3,
                    name: "王五"
                },
                ...this.state.heros
            ]
        })
    }
    render() {
        console.log("i am render")
        return (
            <ul>
                <button onClick={this.addHero}>点击添加王五</button>
                <h1>index as key</h1>
                {this.state.heros.map((hero,index)=>{
                    return <li key={index}>{hero.name}<input type="text" /></li>
                })}
                <h1>age as key</h1>
                {this.state.heros.map((hero,index)=>{
                    return <li key={hero.id}>{hero.name}<input type="text" /></li>
                })}
            </ul>
        )
    }
}

后端程序员入门react笔记——react的diff算法(三),react.js,笔记,算法
我们发现了什么,以index做为key,input框并没有跟着往下移动,id作为key的往下移动了,我们发现问题了,那么为什么index作为key,input框不往下移动呢?就是因为数据的顺序发生变化了,王五被塞进了数组对象的头部,但是diff的时候,由于元素的key是index,还是从0开始的,并没有发生变化,所以input框并不会移动。文章来源地址https://www.toymoban.com/news/detail-835974.html

到了这里,关于后端程序员入门react笔记——react的diff算法(三)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 黑马程序员Docker快速入门到项目部署(学习笔记)

    目录 一、Docker简介 二、安装Docker 2.1、卸载旧版 2.2、配置Docker的yum库 2.3、安装Docker 2.4、启动和校验 2.5、配置镜像加速 2.5.1、注册阿里云账号 2.5.2、开通镜像服务 2.5.3、配置镜像加速 三、快速入门 3.1、部署MYSQL 3.2、命令解读 四、Docker基础 4.1、常见命令 4.1.1、命令介绍 4.1

    2024年01月25日
    浏览(50)
  • 小程序入门笔记(一) 黑马程序员前端微信小程序开发教程

    微信小程序基本介绍 小程序和普通网页有以下几点区别: 运行环境:小程序可以在手机的操作系统上直接运行,如微信、支付宝等;而普通网页需要在浏览器中打开才能运行。 开发技术:小程序采用前端技术进行开发,如HTML、CSS、JavaScript等;而普通网页也是使用类似的前

    2024年02月08日
    浏览(62)
  • 【软考程序员学习笔记】——数据结构与算法基础

    目录  🍊一、数据结构概念和分类 🍊二、数组特点存储方式 🍊三、矩阵 特殊矩阵 非特殊矩阵 🍊四、栈和队列 🍊 五、二叉树的性质 🍊六、二叉树的遍历 (1)前序遍历(先根遍历,先序遍历) (2)中遍历(中根遍历) (3)后序遍历(后根遍历,后序遍历) 🍊七、二叉排序树 🍊八、

    2024年02月12日
    浏览(60)
  • 读程序员的制胜技笔记02_算法与数据结构

    3.1.1.1. 根据你的需要,可以有更智能的算法 3.1.3.1. 算法本身并不意味着它很聪明 3.2.1.1. public static bool Contains(int[] array, int lookFor) { for (int n = 0; n < array.Length; n++) {        if (array[n] == lookFor) {            return true;        }    }    return false; } 3.3.1.1. public sta

    2024年02月06日
    浏览(58)
  • 《黑马程序员2023新版黑马程序员大数据入门到实战教程,大数据开发必会的Hadoop、Hive,云平台实战项目》学习笔记总目录

    本文是对《黑马程序员新版大数据入门到实战教程》所有知识点的笔记进行总结分类。 学习视频:黑马程序员新版大数据 学习时总结的学习笔记以及思维导图会在后续更新,请敬请期待。 前言:配置三台虚拟机,为集群做准备(该篇章请到原视频进行观看,不在文章内详细

    2024年02月03日
    浏览(62)
  • 前端程序员和后端程序员有什么不同?我来告诉你薪资待遇差多少

    在过去,前端程序员的工资可能需要几倍于后端程序员才能相当。因为前端程序员需要处理的是看得见的部分,而且需要兼顾不同的浏览器、设备和操作系统,工作量较大。但是,随着H5的盛行和现代浏览器对HTML5、JavaScript和CSS的支持越来越好,前端程序员可以开发一次代码

    2023年04月22日
    浏览(85)
  • 【程序员英语】【美语从头学】初级篇(入门)(笔记)Lesson 15 At the Department Store 在百货商店

    《美语从头学初级入门篇》 注意:被 删除线 划掉的不一定不正确,只是不是标准答案。 A: Can you help me, please? B: Sure. What can I do for you? A: I’m chosing looking for a gift for my son’s birthday. B: How about this television video game? A: That’s a good idea. Can you gift-wrap it for me , please ? B: Sure. No prob

    2024年02月22日
    浏览(37)
  • 身为一个后端程序员如何快速制作后端管理系统的UI

    我的专业领域在后端开发上,前端我仅仅是熟悉,但是要从头开发一个前端UI界面有点难为人了。那么身为一个后端程序员我们怎么来开发后端管理系统UI界面呢? 市面上有很多后端管理系统的UI模版,但我推荐的layui + lauyimini,虽然技术偏老,也没咋维护了,但是上手简单呀

    2024年02月11日
    浏览(47)
  • 〖程序员的自我修养 - 认知剖析篇⑤〗- 选择前端还是后端?

    人之所以会觉得迷茫,本质上是欠缺对自己的一个控制力、识别庞杂信息、去伪存真的独立思考与认知能力。 说明:该文属于 程序员的自我修养 专栏, 购买任意白宝书体系化专栏可加入 易编程社区, 早鸟价订阅模式除外 。 福利:加入社区的小伙伴们,除了可以获取博主

    2024年02月14日
    浏览(41)
  • Java后端程序员不得不知道的 API 接口常识

    至今我仍清晰地记得,那个电商教程是怎么定义接口的: 管它是增加、修改、删除、带参查询,全是 POST 请求一把梭,比如下面这样: 修改用户的收货地址 POST /xxx-mall/cart/update_address 现在看来,全部用 POST 请求估计是为了传参方便吧。 那个时候自己也没有一个  API 接口需

    2024年02月15日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包