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

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

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

假设原本有一个list,

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

对应的视图为:

图片描述

现在我们删除中间的widget1,list更新成:

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

对应的视图为:

图片描述

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

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

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

所以为了不使用默认的数组index作为key,我们为每个widget加上一个uuid,问题就解决了:

图片描述

注:
如果widget是stateless的,不加key也能够正确删除。
可能的原因大概是stageless的widget每帧都需要重新绘制,因此不管key变不变化都是重绘的,而stateful则是根据state有没有变化来重绘,这样由于key没有变所以state也没有改变。
但是作为开发者的我们,都应该养成添加key的习惯。

如有错误,还望指出!

你可能感兴趣的:(widget,flutter)