React中DOM的diffing算法

React中DOM的diffing算法



前言

我们之前的学习中,一直知道用React可以通过虚拟DOM相同来避免一些非必要的页面渲染,其中就是基于diffing算法的,下面我们一起来探究一下,到底这个算法的执行流程是什么,以及关于key的注意事项

一、Diffing算法的原理图?

在这里插入图片描述

二、diffing算法

1.显示时间案例

1.1 没有被渲染证明

在下面这个案例中,只有时间所在标签会被刷新,标题和input框并不会被重新渲染,一点直接的证明就是我在input框中输入东西,但是它并没有因为时间的变化,而被重新渲染清空
在这里插入图片描述

代码如下(示例):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="test"></div>

<script src="../js/新版本/react.development.js"></script>
<script src="../js/新版本/react-dom.development.js"></script>
<script src="../js/新版本/babel.min.js"></script>
<script src="../js/新版本/prop-types.js"></script>

<script type="text/babel">
    class Time extends React.Component{
        state={time:new Date()}
        componentDidMount()
        {
            setInterval(()=>
            {
                this.setState({time:new Date()});

            },1000)
        }
        render()
        {
            return (
                <div>
                    <h1>欢迎来lmx实验室</h1>
                    <input/>
                    <span>今天的时间是{this.state.time.toTimeString()}</span>
                </div>
            )
        }
    }
    ReactDOM.render(<Time/>,document.getElementById("test"));
</script>

</body>
</html>

1.2 整体还是查询嵌套标签再渲染呢?

那么上面重新渲染的是今天的时间是{this.state.time.toTimeString()}这句话,还是span里面的整个标签呢?其实渲染只能以标签为依据进行整体刷新,那么如果标签里面还嵌套标签呢?
在这里插入图片描述
答案很明显,如下所示,123里面的内容也不会重新渲染,这足以说明,diffing算法是很精明的,他会进行嵌套的循环比较,比较到input发现它的内容和之前的一样,那么就不会进行渲染
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="test"></div>

<script src="../js/新版本/react.development.js"></script>
<script src="../js/新版本/react-dom.development.js"></script>
<script src="../js/新版本/babel.min.js"></script>
<script src="../js/新版本/prop-types.js"></script>

<script type="text/babel">
    class Time extends React.Component{
        state={time:new Date()}
        componentDidMount()
        {
            setInterval(()=>
            {
                this.setState({time:new Date()});

            },1000)
        }
        render()
        {
            return (
                <div>
                    <h1>欢迎来lmx实验室</h1>
                    <input/>
                    <span>今天的时间是{this.state.time.toTimeString()}<input /></span>
                </div>
            )
        }
    }
    ReactDOM.render(<Time/>,document.getElementById("test"));
</script>

</body>
</html>

2.key如何设置?

2.1 diffing如何操作react的渲染过程

在这里插入图片描述

2.2 以index为key的案例展示

首先我们实现一个以index为key实现的人员增加案例,这里为了更好的显示,我们把它加到数组前面
代码如下(示例):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="test"></div>

<script src="../js/新版本/react.development.js"></script>
<script src="../js/新版本/react-dom.development.js"></script>
<script src="../js/新版本/babel.min.js"></script>
<script src="../js/新版本/prop-types.js"></script>

<script type="text/babel">
    class Person extends React.Component{
        state={person:[{id:1,name:"小张",age:"18"},{id:2,name:"小李",age:"19"}]}
        render()
        {

            return(
                <div>
                    <button onClick={this.add}>点我添加小王</button>
                    <ul>{
                        this.state.person.map((one,index)=>
                        {
                            return <li key={index}>{one.name}------{one.age}</li>
                        })
                    }
                    </ul>
                </div>
            )
        }
        add=()=>
        {
            this.setState({person:[{id:3,name:"小王",age:20},...this.state.person]});
        }
    }
    ReactDOM.render(<Person/>,document.getElementById("test"));
</script>

</body>
</html>

结果:我们会发现用index作key会出现几乎全部都需要重新渲染的情况,那么我们的效率就会变低
在这里插入图片描述

2.3 key设为id

在这里插入图片描述
会发现只有小王需要重新渲染,其他的都不用
在这里插入图片描述

2.4 key设为index产生的重大问题


加个input框
  return(
                <div>
                    <button onClick={this.add}>点我添加小王</button>
                    <ul>{
                        this.state.person.map((one,index)=>
                        {
                            return <li key={index}>{one.name}------{one.age}   <input type="text"/></li>
                    })
                    }
                    </ul>
                </div>
            )          

在这里插入图片描述
在这里插入图片描述
会发现点击添加之后,文本框还是和之前的顺序一样,并没有渲染,这个原因大概就是因为上述1.2了,key一样,key里面也有input,那么input就不需要渲染了,因为diffing算法的精明之处
在这里插入图片描述

总结

在本节中,我们深入知道为什么react能够节省渲染界面的数量,以及它的算法流程,以及一些注意事项,期待下一节的学习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值