Flutter中各種Consumer的區(qū)別和使用場景

在項目中履恩,遇到了各種Consumer,剛開始的時候還不知道他們有什么區(qū)別呢蔫,后面通過一些開發(fā)實踐逐漸摸清楚了他們之間的區(qū)別和使用場景切心。
首先飒筑,這些Consumer來源于riverpod這個庫,主要是提升開發(fā)者對provider的使用绽昏,便于獲取provider协屡,實現(xiàn)相關(guān)的狀態(tài)管理。

1. ConsumerWidget

是一個StatefulWidget全谤,但是不需要我們?nèi)崿F(xiàn)相關(guān)的Widget和State肤晓。內(nèi)部已經(jīng)幫我們封裝實現(xiàn)好了。使用時认然,只要繼承ConsumerWidget补憾,實現(xiàn)Widget build(BuildContext context, WidgetRef ref);函數(shù)即可。然后通過ref獲取需要的provider

2. Consumer

是對ConsumerWidget的進一步封裝卷员。對于一些Widget我們不想去新建一個類來繼承ConsumerWidget盈匾,那我們可以使用Consumer來包裹Widget。
例子:

Consumer(
    builder: (context, ref, child) {
        final value = ref.watch(helloWorldProvider);
        return Text(value);
    },
);

3. HookConsumerWidget

HookConsumerWidget是HookWidget和ConsumerWidget的結(jié)合子刮。HookWidget的主要作用是在封裝好的StateLessWidget威酒,實現(xiàn)一些需要initState或者dispose回調(diào)的一些方法,比如AnimationController或者是做一些緩存挺峡。
而ConsumerWidget雖然是StatefulWidget葵孤,但是沒辦法回調(diào)initState和dispose,所以通過將HookConsumerWidget橱赠,就可以在使用Consumer的時候尤仍,實現(xiàn)一些需要initState和dispose的邏輯。

@override
Widget build(BuildContext context, WidgetRef ref) {
  // 初始化一個變量狭姨,并且只會執(zhí)行一次
  final count = useState<T>(initValue);
  // 改變變量的值宰啦,并且會刷新widget,相當于setState
  count.value++;

  useEffect({
    // 做一些initState的操作
    // 這里的執(zhí)行只有Widget第一次build的時候才會執(zhí)行
    return method.call();// 這個方法在widget dispose的時候會執(zhí)行饼拍。
  })

  // 一條語句可以實現(xiàn)animationController的初始化和自動dispose
  final animationCtrl =
        useAnimationController(duration: 300.milliseconds, initialValue: 0);
}

更多Hook用法參考:Hook的用法

4. HookConsumer

HookConsumer就是對HookConsumerWidget的進一步封裝赡模,對于一些不需要新建一個類去繼承HookConsumerWidget的,那就直接用HookConsumer师抄。就如同Consumer和ConsumerWidget之間的關(guān)系一樣漓柑。

5. RiverpodConsumer

是內(nèi)部自己實現(xiàn)的一個HookConsumer,傳入listenable和builder可以實現(xiàn)provider的監(jiān)聽和rebuild叨吮。對于只需要監(jiān)聽單一變量時辆布,使用RiverpodConsumer是比較方便的,但是如果一個widget需要監(jiān)聽多個變量茶鉴,對這些變量做出對應的widget更新锋玲,那是不建議使用RiverpodConsumer進行多層嵌套的。因為RiverpodConsumer實際內(nèi)部還是用Consumer實現(xiàn)的涵叮,而Consumer實際是一個StatefulWidget惭蹂,所以RiverpodConsumer的嵌套實際上就是StatefulWidget的嵌套伞插,這個是損耗性能并且是沒必要的操作。還降低了代碼的可讀性剿干。

6. WidgetRef的監(jiān)聽

WidgetRef中一共有4種調(diào)用provider的方式蜂怎,分別是read, listen, watch和refresh穆刻,其中前3種比較常見和易用置尔。read是獲取provider的當前狀態(tài),如果后續(xù)provider發(fā)生改變了氢伟,那么獲得的值并不會更新榜轿。并且,當provider是AutoDispose的朵锣,那么在read完這個provider之后谬盐,provider就會被dispose,即使當前頁面沒有銷毀诚些,provider也同樣會被dispose飞傀。
而listen和watch是可以監(jiān)聽provider的變化。他們的區(qū)別是诬烹,listen是監(jiān)聽provider的變化砸烦,然后在回調(diào)函數(shù)中做對應的邏輯處理。而watch是監(jiān)聽provider的變化绞吁,然后讓·ref對應的widget自動重建幢痘。
所以,當我們使用watch的時候應該盡可能的讓底層的ref去做監(jiān)聽家破,來避免大量widget的重建颜说。并且監(jiān)聽的時候盡量使用provider.select((value) => value.member)監(jiān)聽provider中的某個變量的變化。來避免provider其他不相關(guān)的變量發(fā)生變化引起不必要的重建汰聋。
另外门粪,當我們監(jiān)聽provider中的集合時,如果是集合中的元素發(fā)生變化(增刪改)烹困,通過provider.select((value) => value.collection)是沒辦法監(jiān)聽到的玄妈,此時只能ref.watch(provider)監(jiān)聽整個provider來獲取集合元素的變化。除非是在集合元素發(fā)生變化后韭邓,重新對集合進行賦值措近,那就可以監(jiān)聽select
對provider中的對象同理女淑。如果是修改對象的某個成員變量瞭郑,只監(jiān)聽該對象是無法獲得該對象的某個成員變量的變化。需要監(jiān)聽該對象的成員變量鸭你。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屈张,一起剝皮案震驚了整個濱河市擒权,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌阁谆,老刑警劉巖碳抄,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異场绿,居然都是意外死亡剖效,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門焰盗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來璧尸,“玉大人,你說我怎么就攤上這事熬拒∫猓” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵澎粟,是天一觀的道長蛀序。 經(jīng)常有香客問我,道長活烙,這世上最難降的妖魔是什么徐裸? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮瓣颅,結(jié)果婚禮上倦逐,老公的妹妹穿的比我還像新娘。我一直安慰自己宫补,他們只是感情好檬姥,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著粉怕,像睡著了一般健民。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贫贝,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天秉犹,我揣著相機與錄音,去河邊找鬼稚晚。 笑死崇堵,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的客燕。 我是一名探鬼主播鸳劳,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼也搓!你這毒婦竟也來了赏廓?” 一聲冷哼從身側(cè)響起涵紊,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎幔摸,沒想到半個月后摸柄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡既忆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年驱负,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尿贫。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡电媳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出庆亡,到底是詐尸還是另有隱情,我是刑警寧澤捞稿,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布又谋,位于F島的核電站,受9級特大地震影響娱局,放射性物質(zhì)發(fā)生泄漏彰亥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一衰齐、第九天 我趴在偏房一處隱蔽的房頂上張望任斋。 院中可真熱鬧,春花似錦耻涛、人聲如沸废酷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽澈蟆。三九已至,卻和暖如春卓研,著一層夾襖步出監(jiān)牢的瞬間趴俘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工奏赘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留寥闪,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓磨淌,卻偏偏與公主長得像疲憋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子伦糯,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容