跳到主要內容

為什麼選擇 Riverpod?

什麼是 Riverpod?

Riverpod(Provider 的異序詞)是 Flutter/Dart 的反應式快取框架。

Riverpod 使用宣告式和反應式程式設計,為您處理應用程式的大部分邏輯。 它可以透過內建的錯誤處理和快取來執行網路請求,同時在必要時自動重新獲取資料。

動機

現代應用程式很少提供呈現其使用者介面所需的所有資訊。 相反,資料通常是從伺服器非同步獲取的。

問題是,使用非同步程式碼很困難。 儘管 Flutter 提供了一些建立狀態變數並在更改時重新整理 UI 的方法,但它仍然相當有限。 許多挑戰仍未解決:

  • 非同步請求需要在本地快取,因為每當 UI 更新時就重新執行非同步請求是不合理的。
  • 由於我們有一個快取,如果我們不關心的話,我們的快取可能會過時。
  • 我們還需要處理錯誤和載入狀態。

大規模解決這些問題可能很困難,並且它們會受到大量功能的影響,例如:

  • 下拉重新整理
  • 無限列表/上劃載入
  • 鍵入時搜尋
  • 對非同步請求進行去抖動
  • 不再使用非同步請求時取消非同步請求
  • 樂觀 UI (注:主動積極的更新 UI 以實現良好的使用者體驗)
  • 離線模式
  • ……

這些功能可能很難實現,但對於良好的使用者體驗至關重要。
然而,很少有軟體包嘗試直接解決這些問題,而且很多工作必須手動完成。

這就是 Riverpod 的用武之地。
Riverpod 試圖透過提供一種新的、獨特的業務邏輯編寫方式來解決這些問題, 這種方式的靈感來自 Flutter 小部件。 在許多方面,Riverpod 可以與小部件相媲美,但僅限於狀態管理。

使用這種新方法,這些複雜的功能大多是預設完成的。 剩下的就是專注於你的 UI。

不信?舉個例子。 以下程式碼片段是使用 Riverpod 實現的 Pub.dev 客戶端應用程式的簡化版本。


// Fetches the list of packages from pub.dev

Future<List<Package>> fetchPackages(
Ref ref, {
required int page,
String search = '',
}) async {
final dio = Dio();
// Fetch an API. Here we're using package:dio, but we could use anything else.
final response = await dio.get<List<Object?>>(
'https://pub.dartlang.org/api/search?page=$page&q=${Uri.encodeQueryComponent(search)}',
);

// Decode the JSON response into a Dart class.
return response.data?.map(Package.fromJson).toList() ?? const [];
}

此程式碼片段是在處理錯誤/載入狀態時,“鍵入時搜尋”+“下拉重新整理”+“無限列表”所需的所有業務邏輯。