在作一個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的習慣。
若有錯誤,還望指出!