Flutter Riverpod 輕鬆學,簡單處理狀態管理!

Yii Chen
9 min readApr 24, 2022

快速了解每個Provider要如何操作

https://riverpod.dev/img/logo.png

官方

https://riverpod.dev/

Package

https://pub.dev/packages/flutter_riverpod

說明

如果Provider是InheritedWidget的簡化,那麼Riverpod就是從頭開始對InheritedWidget的重新實現。

如果Provider是蠟燭,那麼Riverpod就是燈泡。它們的用途非常相似,但我們不能通過改進蠟燭來製造燈泡。

功能

Riverpod保有Provider功能,與自身優點

  • 能夠安全地創建、觀察和結束狀態,不必擔心在Widget重建時狀態消失
  • 狀態在 Flutter 的 DevTool 中清楚可見,WidgetTree上一覽無遺
  • 方便組合與測試
  • 當我們有多個InheritedWidget時提高可讀性
  • 通過單向數據流使應用更具擴展性

比Provider更好的部分

  • 讀取的物件實體是編譯安全的
編譯時就能找出問題,不會有運行時的異常,例:ProviderNotFoundException。
  • 它使Provider模式更加靈活
1. 能夠擁有多個相同型別的Provider2. Provider可以依賴或監聽其他Provider3. 沒有在使用Provider的時候,進行關閉,實現記憶體釋放4. 可以將Provider設置成private5. 幫Widget區塊綁定狀態裡的某個數值,當此數值更新時UI才會刷新
  • 輕鬆管理異步狀態,使用方式類似RxDart的Subject

Riverpod 與 get_it 和 GetX 也有些共通點

1. 單立模式2. 局部刷新

Provider

全局的Provider,供大家取用

Widget繼承ConsumerWidget,build()裡提供WidgetRef參數,負責存取Provider

Provider局部刷新

使用Consumer進行局部更新,節省效能

build parameters
1. BuildContext
2. WidgetRef,存取Provider
3. Widget(child)

StateProvider

  • 適合用來做簡單的資料刷新,不需要其他邏輯,更新state也就是內容後,立即通知UI更新
  • 內建使用的Notifier是StateController,繼承StateNotifier
  • 監聽數值的時候使用watch()操作provider
  • 更新數值的時候使用read()操作provider

watch()取得Privider提供的最新狀態

read()取得Privider的StateNorifier,更新狀態

另一種更新方式:
update() ➤ 提供一個參數,代表當前狀態,取得後進行改變

StateNotifierProvider

  • 與 StateProvider 類似
  • 可以自定義StateNotifier,實作更新內容的函式與邏輯

StateNotifierProvider 搭配 freezed 套件

使用 freezed 產生資料的狀態類,監聽狀態的callback顯示指定UI

StateNotifier的泛型資料為狀態類,並在不同時機更新為對應的狀態

Widget部分一樣用watch存取Provider,取得定義的NumberState,並使用when函式,裡面提供我們自定義的四種狀態,在這裡可以處理每個狀態的觸發,進行不同的UI呈現

ChangeNotifierProvider

  • 支援可變的狀態、數據結構,狀態比較多比較複雜的情境下使用
  • 與StateNotifier的區別,需要額外使用notifyListeners()通知更新

Consumer進行Widget局部更新

點擊按鈕後更新狀態

注意❗️

  1. ChangeNotifierProvider適合給原本使用Provider套件的開發者,可以進行輕鬆過渡
  2. 官方建議使用StateNotifierProvider代替ChangeNotifierProvider,因為ChangeNotifier通常到後期會包含各式各樣的狀態,較難維護與測試,也可能產出更多Bug。

FutureProvider

  • 執行和緩存異步操作(例如網絡請求)
  • 很好地處理資料的成功、載入與錯誤狀態
  • 結合多個非同步操作

模擬遠端請求資料,拿到金鑰

透過Provider取得包裹AsyncValue的狀態,簡單進行三種狀態的處理,顯示特定UI

StreamProvider

  • 適合監聽 Firebase stream 或 Socket event

像StreamBuilder,有幾個特色

  1. 它允許其他Provider使用ref.watch取得stream
  2. 由於AsyncValue,它確保正確處理加載和錯誤情況
  3. 它不需要區分 廣播流 普通流
  4. 它緩存流發出的最新值,確保如果在發出事件後添加listener,listener仍然可以立即訪問最新事件
  5. 它允許在測試期間使用假的stream,透過 override StreamProvider

StreamProvider 搭配 StreamController 的範例

首先建立一個 LoadingProcesser 類,負責操作 loading 進度

每當stream更新時將數值透過yield返回並更新畫面,直到100再透過StreamController關閉這個Stream。這裡也可以直接return Stream,某個時刻在進行Stream的釋放

--

--

Yii Chen

Flutter Lover || Organizer FlutterTaipei || Writer, Speaker || wanna make Flutter strong in Taiwan. https://linktr.ee/yiichenhi