• 十一、DOM的Diffing算法


    一、验证Diffing算法

    在这里插入图片描述

     

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>title>
    8. head>
    9. <body>
    10. <div id="app">div>
    11. <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin>script>
    12. <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin>script>
    13. <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    14. <script src="https://unpkg.com/prop-types@15.6.2/prop-types.js">script>
    15. <script type="text/babel">
    16. //创建组件
    17. class Timer extends React.Component{
    18. state={date:new Date()}
    19. componentDidMount(){
    20. console.log("ok");
    21. setInterval(() => {
    22. this.setState({date:new Date()})
    23. }, 1000);
    24. }
    25. render (){
    26. //只有整个span标签(不只是内容还有span标签)更新了,h1和input没有变化没有更新还是原来的真实DOM,在input中输入内容内容不变所以没有更新DOM还是原来的
    27. return(
    28. <div>
    29. <h1>helloh1>
    30. <input type="text"/>
    31. <span>现在是:{this.state.date.toTimeString()}span>
    32. div>
    33. )
    34. }
    35. }
    36. //2.渲染虚拟DOM到页面
    37. ReactDOM.render(<Timer />,document.getElementById('app'))
    38. script>
    39. body>
    40. html>

    二、key的作用

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>title>
    8. head>
    9. <body>
    10. <div id="app">div>
    11. <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin>script>
    12. <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin>script>
    13. <script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
    14. <script src="https://unpkg.com/prop-types@15.6.2/prop-types.js">script>
    15. <script type="text/babel">
    16. /*
    17. 2.2 关于key的经典面试题
    18. 1). react/vue中的key有什么作用?(key的内部原理是什么?)
    19. 2). 为什么遍历列表时,key最好不要用index?
    20. 2.2.1 虚拟DOM中key的作用
    21. 1). 简单的说: key是虚拟DOM对象的标识, 在更新显示时key起着极其重要的作用。
    22. 2). 详细的说: 当状态中的数据发生变化时,react会根据【新数据】生成【新的虚拟DOM】, 随后React进行【新虚拟DOM】与【旧虚拟DOM】的diff比较,比较规则如下:
    23. a. 旧虚拟DOM中找到了与新虚拟DOM相同的key:
    24. (1).若虚拟DOM中内容没变, 直接使用之前的真实DOM
    25. (2).若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM
    26. b. 旧虚拟DOM中未找到与新虚拟DOM相同的key
    27. 根据数据创建新的真实DOM,随后渲染到到页面
    28. 2.2.2 用index作为key可能会引发的问题
    29. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
    30. 会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低
    31. 如果结构中还包含输入类的DOM:
    32. 会产生错误DOM更新 ==> 界面有问题
    33. 注意!如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,
    34. 仅用于渲染列表用于展示,使用index作为key是没有问题的
    35. 2.2.3 开发中如何选择key?
    36. 最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值
    37. 如果确定只是简单的展示数据,用index也是可以的
    38. */
    39. /*
    40. 慢动作回放-----使用index索引值作为key
    41. 初始数据:
    42. {id:1,name:'小张',age:18},
    43. {id:2,name:'小李',age:19}
    44. 初始的虚拟DOM:
    45. <li key=0>小张----18li>
    46. <li key=1>小李----19li>
    47. 更新后的数据
    48. {id:3,name:'小王',age:20}
    49. {id:1,name:'小张',age:18},
    50. {id:2,name:'小李',age:19}
    51. 更新后的虚拟DOM:(小王是先遍历的所以是0)
    52. <li key=0>小王----18li>
    53. <li key=1>小张----18li>
    54. <li key=2>小李----19li>
    55. 旧的(初始)虚拟DOM和更新后的新的虚拟DOM对比
    56. 明明小张和小李可以复用,但是用了index作为key,导致索引值变了,导致了没有必要的真实DOM更新。
    57. 慢动作回放-----使用id(唯一标识)作为key
    58. 初始数据:
    59. {id:1,name:'小张',age:18},
    60. {id:2,name:'小李',age:19}
    61. 初始的虚拟DOM:
    62. <li key=1>小张----18li>
    63. <li key=2>小李----19li>
    64. 更新后的数据
    65. {id:3,name:'小王',age:20}
    66. {id:1,name:'小张',age:18},
    67. {id:2,name:'小李',age:19}
    68. 更新后的虚拟DOM:(小王是先遍历的所以是0)
    69. <li key=3>小王----18li>
    70. <li key=1>小张----18li>
    71. <li key=2>小李----19li>
    72. 旧的(初始)虚拟DOM和更新后的新的虚拟DOM对比
    73. 没有key等于3的虚拟DOM那就转为真实DOM放到页面
    74. 问旧的虚拟DOM你那有key等于1和key等于2的虚拟DOM吗,有,那么就直接复用了,不再生成新的真实DOM了也不往页面上放了
    75. */
    76. //创建组件
    77. class Person extends React.Component{
    78. state={
    79. person:[
    80. {id:1,name:'小张',age:18},
    81. {id:2,name:'小李',age:19}
    82. ]
    83. }
    84. add=()=>{
    85. const {person}=this.state
    86. const p={id:person.length+1,name:'小王',age:20}
    87. this.setState({person:[p,...person]})
    88. }
    89. render (){
    90. return(
    91. <div>
    92. <h2>展示人员信息h2>
    93. <button onClick={this.add}>添加一个小王button>
    94. <h3>使用index索引值作为keyh3>
    95. <ul>
    96. {
    97. this.state.person.map((personObj,index)=>{
    98. return <li key={index}>{personObj.name}----{personObj.age}<input type="text"/>li>
    99. })
    100. }
    101. ul>
    102. <br/><br/>
    103. <h3>使用id(数据的唯一标识)作为keyh3>
    104. <ul>
    105. {
    106. this.state.person.map((personObj)=>{
    107. return <li key={personObj.id}>{personObj.name}----{personObj.age}<input type="text"/>li>
    108. })
    109. }
    110. ul>
    111. div>
    112. )
    113. }
    114. }
    115. //2.渲染虚拟DOM到页面
    116. ReactDOM.render(<Person />,document.getElementById('app'))
    117. script>
    118. body>
    119. html>

  • 相关阅读:
    买卖股票的最佳时机(系列)
    k8s docker cgroup驱动问题 —— 筑梦之路
    LeetCode_730_每日温度
    Android 插件开发框架 总结
    vue3项目中引用tailwindcss与heroicons
    【SUMO学习】初级 Driving in Circles
    三维模型3DTile格式轻量化在三维展示效果上的重要性分析
    【Mysql】复合查询详解+实战操作(多表查询、自链接、子查询等)
    [含毕业设计论文+PPT+源码等]springboot巧匠家装小程序+Java后台管理系统|前后分离VUE
    大语言模型构建的主要四个阶段(各阶段使用的算法、数据、难点以及实践经验)
  • 原文地址:https://blog.csdn.net/chunxiaqiudong5/article/details/126287113