flutter的key在widget list的做用以及必要性

在作一个flutter的项目过程当中,体会到了key在widget渲染中发挥的做用以及开发者须要避免的坑,在次提出共勉vue

与react的diff算法相似(vue的也是),flutter在渲染同级相似的item的时候也是采用key值判断来从新渲染的。
所以若是你的业务中若是包含了一个同类型的widget list,记得要为每一个widget加上一个key,不然flutter也是默认使用item在list的index做为key,这样就会遇到下面这个常见的坑了:react

假设本来有一个list,算法

list = [widget0: {key: 0, data: 10 ...}, widget1: {key: 1, data: 20 ...}, widget2: {key: 2, data: 30 ...}]

对应的视图为:数组

图片描述

如今咱们删除中间的widget1,list更新成:less

list = [widget0: {key: 0, data: 10 ...}, widget2: {key: 1, data: 30 ...}]

对应的视图为:ui

图片描述

能够看到,widget1没有被删除,而是widget2被删除了,这显示是错误的。spa

缘由便在于:
虽然widget1在list中确实删除了,但后来顶上的widget2的key(在数组的index)变成了1
而当fultter执行diff算法的时候,是根据先后widget的key是否变化来判断的code

在这个场景下,"key = 1"这个key仍然存在,因此flutter不会去从新渲染上一帧key为1的widget1;而"key = 2"这个key删除了,flutter就删除掉上一帧key为2的widget2。blog

因此为了避免使用默认的数组index做为key,咱们为每一个widget加上一个uuid,问题就解决了:图片

图片描述

注:
若是widget是stateless的,不加key也可以正确删除。
可能的缘由大概是stageless的widget每帧都须要从新绘制,所以无论key变不变化都是重绘的,而stateful则是根据state有没有变化来重绘,这样因为key没有变因此state也没有改变。
可是做为开发者的咱们,都应该养成添加key的习惯。

若有错误,还望指出!

相关文章
相关标签/搜索