一 react 组件元素的 diff 算法

二 key 的理解

概述

react 中的key 属性,它是一个特殊的属性,它的出现不是给开发者用的(例如你为一个组件设置key之后不能获取组件的这个key props),而是给react自己用的。

key 的作用

key不是用来提升react的性能的,不过用好key对性能是有帮组的。

react 利用 key 来识别组件,它是一种身份标识标识。每个 key 对应一个独立的组件,在前后渲染过程中,相同的 key会被 react 认为是同一个组件。

  • key 相同,会重新渲染 props 属性。
  • key 不同,即在下次渲染中有新的 key 值出现,会销毁之前的组件,然后重新创建该组件。

key 的使用场景

1 用数组动态创建子组件的情况。

尽量不用 index 作为列表的唯一 key。

{this.state.data.map((v,idx)=><Item key={idx} v={v} />)}
// 开始时:['a','b','c']=>
<ul>
<li key="0">a <input type="text"/></li>
<li key="1">b <input type="text"/></li>
<li key="2">c <input type="text"/></li>
</ul> // 数组重排 -> ['c','b','a'] =>
<ul>
<li key="0">c <input type="text"/></li>
<li key="1">b <input type="text"/></li>
<li key="2">a <input type="text"/></li>
</ul>

分析:

  1. 重新排序后,组件重新生成虚拟 dom,然后新旧虚拟 dom 进行 diff 对比。
  2. 拿 key 为 0 的组件举例。获取到新虚拟 dom 中 key 为 0 的组件,然后从旧的虚拟 dom 中找到 key 为 0 的组件。由同一个 key 可判断是同一个组件进行 diff。react 会保证组件的实例不变。只更新 props 值。然后递归遍历他的子节点,发现只有文本节点前后不一致,调用 componentWillReceiveProps -> componentWillUpdate -> render 依次更新组件的属性。
  3. 因为 input 元素在对比中并没有变化,且其是非受控组件,又与父组件传入的任一props没有关联,所以其输入的 value 值会保存在 input 中,导致排序后,内容和组件的顺序错乱。

key的值要稳定唯一

  1. 不能使用random来生成key的值。

    • random 函数的不确定性,会导致同一组件的 key 值渲染前后不一致。react 认为其不是同一个组件,会先将其从 dom 中移除,然后再重新生成 dom。不会重新渲染 props。性能开销相对较大。
  2. 可以自定一个 count 解决。每次数组有一个子项,便向子项数据中加入 key 这一属性,遍历时将 key 赋值给属性。保证 key 值得唯一性。

2 为一个复杂逻辑组件添加一个 key,然后再次渲染时修改它的 key。以达到先销毁该组件实例,再去重新渲染该组件的目的。实为复原组件的默认状态。

key 的其他注意事项

  • key值的唯一是有范围的,即在数组生成的同级同类型的组件上要保持唯一,而不是所有组件的key都要保持唯一。
  • 不仅仅在数组生成组件上,其他地方也可以使用key,主要是react利用key来区分组件的,相同的key表示同一个组件,react不会重新销毁创建组件实例,只可能更新;key不同,react会销毁已有的组件实例,重新创建组件新的实例。

深入理解React key的更多相关文章

  1. React key究竟有什么作用?深入源码不背概念,五个问题刷新你对于key的认知

    壹 ❀ 引 我在[react]什么是fiber?fiber解决了什么问题?从源码角度深入了解fiber运行机制与diff执行一文中介绍了react对于fiber处理的协调与提交两个阶段,而在介绍协调时 ...

  2. 深入理解React(二) —— 数据流和事件原理

    版权声明:本文由左明原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/158 来源:腾云阁 https://www.qclou ...

  3. 深入理解React、Redux

    深入理解React.ReduReact+Redux非常精炼,良好运用将发挥出极强劲的生产力.但最大的挑战来自于函数式编程(FP)范式.在工程化过程中,架构(顶层)设计将是一个巨大的挑战.要不然做出来的 ...

  4. 理解 React,但不理解 Redux,该如何通俗易懂的理解 Redux?

    作者:Wang Namelos链接:https://www.zhihu.com/question/41312576/answer/90782136来源:知乎著作权归作者所有.商业转载请联系作者获得授权 ...

  5. 理解 React,但不理解 Redux,该如何通俗易懂的理解 Redux?(转)

    作者:Wang Namelos 链接:https://www.zhihu.com/question/41312576/answer/90782136来源:知乎 解答这个问题并不困难:唯一的要求是你熟悉 ...

  6. 理解 React Hooks 心智模型:必须按顺序、不能在条件语句中调用的规则

    前言 自从 React 推出 hooks 的 API 后,相信大家对新 API 都很喜欢,但是它对你如何使用它会有一些奇怪的限制.比如,React 官网介绍了 Hooks 的这样一个限制: 不要在循环 ...

  7. react——key值的理解

    key不是给开发者使用的,是给react在diff算法中使用的,diff算法会比较新旧虚拟dom,并且是同层比较,当同一层中有多个元素的时候,会比较这一层的key值, 如果key相同,属性改变积极更新 ...

  8. 深度理解 React Suspense(附源码解析)

    本文介绍与 Suspense 在三种情景下使用方法,并结合源码进行相应解析.欢迎关注个人博客. Code Spliting 在 16.6 版本之前,code-spliting 通常是由第三方库来完成的 ...

  9. 深入理解react中的虚拟DOM、diff算法

    文章结构: React中的虚拟DOM是什么? 虚拟DOM的简单实现(diff算法) 虚拟DOM的内部工作原理 React中的虚拟DOM与Vue中的虚拟DOM比较 React中的虚拟DOM是什么?   ...

随机推荐

  1. put out|smashed|As soon as|provided

    CONJ-SUBORD 如果:假如:只要If you say that something will happen provided or provided that something else h ...

  2. python学习笔记(4)数据类型-元组

    元组其实和列表一样,不一样的是,元组的值不能改变,一旦创建,就不能再改变了,比如说,要存数据库的连接信息,这个连接信息在程序运行中是不能被改变的,如果变了那数据库连不上了,就程序就完犊子了,这样的就可 ...

  3. 接口测试-chap3-https请求证书问题

    接口地址如果是HTTPS,需要安装证书,或者在发送请求时传入参数verify=False,表示忽略 res = requests.get(url, verify=False)

  4. python中sorted和sorted 、reversed和reverse的使用。

    #encoding = utf-8 list = [1,8,3,6] print(list.sort()) #None print(list) #[1,3,6,8] print(sorted(list ...

  5. CF580D_Kefa and Dishes

    D. Kefa and Dishes time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  6. Widgets学习

    ListView ListView RecyclerView RecyclerView ExpandableListView 关闭箭头 elvMsg.setGroupIndicator(null); ...

  7. [转]<版本一>写代码的小女孩

    天冷极了,下着雪,又快黑了.这是NOIP的前夜.在这又冷又黑的晚上,一个衣衫破烂的小女孩在机房敲着代码.她从班里逃出来的时候还拿着一本算导,但是有什么用呢?那是一本很破旧的书——那么大,一向是她妈妈垫 ...

  8. mysql表关系

    表与表之间的关系 """ 把所有数据都存放于一张表的弊端 1.组织结构不清晰 2.浪费硬盘空间 3.扩展性极差 """ # 上述的弊端产生原 ...

  9. Unique Snowflakes(窗口滑动)

    题目: Emily the entrepreneur has a cool business idea: packaging and selling snowflakes. She has devis ...

  10. Mybatis分页插件的使用流程

    如果你也在用Mybatis,建议尝试该分页插件,这一定是最方便使用的分页插件.该插件支持任何复杂的单表.多表分页. 1.引入PageHelper的jar包 在pom.xml中添加如下依赖: 12345 ...