flutter : didUpdateWidget 的由來和目的
由來:
父層widget改變時,子層的widget會重新create new instance,而如果是StatefullWidget他的element會有update的流程,依序做 element.widget = new widget=>state._widget = widget = new widget => state.didUpdateWidget(old widget) => rebuild
目的:
當走進didUpdateWidget代表state的狀態會被沿用,這時候有些狀態的值需要重新更新,就需要在didUpdateWidget裡面做,因為只有這個function被執行時才代表state被沿用了。
延伸:
上面的解釋我們稱呼state被沿用了也同時代表element被沿用了,多解釋一點element會透過call updateChild(element child, widget? newWidget,…)來做更新子element,會有三種情況
1. new child widget = null && old child element != null => element.deactivateChild(child) 把兒子殺掉
2. new widget == old widget => 1.1 new old不同slot==> update new chlid to new slot 1.2 Widget.canUpdate == true ==> element.update(new widget)
3. old child element != null && new widget != old widget && !Widget.canWidget(new,old) => element.deactivateChild(child) , element.inflateWidget(new widget , new slot)
4. old child element == null => inflateWidget(new widget ,new slot) 建一個新的element
element一定會有widget
下集跟大家介紹state vs key vs didUpdateWidget的關係
上次提到說state會被沿用,這代表widget被更新時state不會被重新創建,有時我們會透過widget帶入一些參數,並在createState method中帶進去state,如果state也沒重建就沒問題,但是沒有重建代表不會走近createState / state contructor / init state這三個method所以導致新的參數沒有apply
解法一 : 前面有提到把這些邏輯移到didUpdateWidget,然後用newWidget.initailPage assgin到state.initialPage
解法貳(暴力解):直接上個key讓CanUpdateWidget是false,觸發child element重建
CanUpdateWidget邏輯: old widget runtime type == new widget runtime type && old.key == new.key