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

React as a UI Runtime(五、列表)

通过比较树中的元素是否在同一位置,通常已经足够判断是否是重用还是再次创建通信组件了。
但是这只在子元素的位置是静止的并且不需要重排。在我们的上述的例子中,即使message不存在,我们仍然只带input在message之后,并且没有其他的子元素。

对于动态列表,我们不能确定顺序是否会一致:

function ShoppingList({ list }) {
  return (
    <form>
      {list.map(item => (
        <p>
          You bought {item.name}
          <br />
          Enter how many do you want: <input />
        </p>
      ))}
    </form>
  )
}

如果shopping项目没有被重排,React把所有的p和input元素看做是一个类型,并且不知道怎么移动他们。(从react的视角看,是商品的项目本身改变了,而不是他们的顺序)
React执行的10个商品项目的重排会是下面这样:

for (let i = 0; i < 10; i++) {
  let pNode = formNode.childNodes[i];
  let textNode = pNode.firstChild;
  textNode.textContent = 'You bought ' + items[i].name;
}

So instead of re-ordering them, React would effectively update each of them. This can create performance issues and possible bugs. For example, the content of the first input would stay reflected in first input after the sort — even though conceptually they might refer to different products in your shopping list!

This is why React nags you to specify a special property called key every time you include an array of elements in your output:

所以React会更新每一个元素而不是对他们进行重排。这可能会引起性能问题和可能的bugs。例如,当商品列表的顺序改变时,原本在第一个输入框的内容仍然会存在于现在的第一个输入框中 — 尽管事实上在商品列表里它应该代表着其他的商品!
这就是为什么React会提示你为每一个数组的遍历元素标记一个独有的key属性:

function ShoppingList({ list }) {
  return (
    <form>
      {list.map(item => (
        <p key={item.productId}>
          You bought {item.name}
          <br />
          Enter how many do you want: <input />
        </p>
      ))}
    </form>
  )
}
key 给予 React 判断子元素是否真正相同的能力,即使在渲染前后它在父元素中的位置不是相同的。

当 React 在 <form> 中发现 <p key="42"> ,它就会检查之前版本中的 <form> 是否同样含有 <p key="42"> 。即使 <form> 中的子元素们改变位置后,这个方法同样有效。在渲染前后当 key 仍然相同时,React 会重用先前的宿主实例,然后重新排序其兄弟元素。

需要注意的是 key 只与特定的父亲 React 元素相关联,比如 <form> 。React 并不会去匹配父元素不同但 key 相同的子元素。(React 并没有惯用的支持对在不重新创建元素的情况下让宿主实例在不同的父元素之间移动。)

给 key 赋予什么值最好呢?最简单的答案就是:哪时候一个元素不会改变即使它在父元素中的顺序被改变? 例如,在商品列表中,商品本身的 ID 是区别于其他兄弟商品的标识。

相关文章:

  • 如何进阶一名有竞争力的程序员?
  • 实现简单的正则表达式引擎
  • 读写配置文件模块configparser—参考杨永明博客
  • Android的WIFI局域网对讲机
  • todo: 改变字体的动画
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • 翻译:Hystrix - How To Use
  • k8s应用机密信息与配置管理(九)--技术流ken
  • 如何使用 JavaScript 解析 URL
  • patchwork.ffmpeg.org 里面未被选中的优秀代码
  • c# 设计模式
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • __setitem__,__getitem,__delitem__的作用
  • MQ框架的比较
  • 更好用的集群限流功能,Sentinel 发布 v1.4.2
  • 3.7、@ResponseBody 和 @RestController
  • JavaScript函数式编程(一)
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • php ci框架整合银盛支付
  • Vue小说阅读器(仿追书神器)
  • 产品三维模型在线预览
  • 给新手的新浪微博 SDK 集成教程【一】
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 微信小程序:实现悬浮返回和分享按钮
  • 我建了一个叫Hello World的项目
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • Java性能优化之JVM GC(垃圾回收机制)
  • ​2020 年大前端技术趋势解读
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (Python第六天)文件处理
  • (ZT) 理解系统底层的概念是多么重要(by趋势科技邹飞)
  • (待修改)PyG安装步骤
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (七)c52学习之旅-中断
  • (算法)N皇后问题
  • (算法)前K大的和
  • (一) springboot详细介绍
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET Micro Framework初体验
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .NET微信公众号开发-2.0创建自定义菜单
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • /etc/fstab和/etc/mtab的区别
  • @RequestBody与@ResponseBody的使用
  • @RequestMapping 的作用是什么?
  • @select 怎么写存储过程_你知道select语句和update语句分别是怎么执行的吗?
  • [ IOS ] iOS-控制器View的创建和生命周期
  • [AutoSAR 存储] 汽车智能座舱的存储需求
  • [C#]猫叫人醒老鼠跑 C#的委托及事件
  • [Deep Learning] 神经网络基础