Flutter 入門與實戰(四十六):狀態管理有N 種寫法,你知道麼?

島上碼農發表於2021-08-09

這是我參與8月更文挑戰的第9天,活動詳情檢視:8月更文挑戰

楔子

話說孔乙己轉行做了程式設計師,聽聞近年來大前端比較火,也跟風學了一陣。什麼 Vue,React,Angular 都瞭解一點。這段時間,行業巨頭谷歌出了個 Flutter,號稱要一套程式碼搞定整個前端,孔乙己自然不願放過。

這天孔乙己逛到了掘金社群,裡面大佬太多,他怕自己太業餘露餡。知道不能和他們談天,便只好向初學者說話。有一回在我的評論區問道,“你學過 Flutter麼?” 我略略回了個表情。 他說,“學過,……我便考你一考。Flutter的狀態管理,怎樣寫的?” 我想,水平和我一樣的人,也配考我麼?便沒有回訊息,不再理會。 孔乙己等了許久,再一次評論道,“不能寫罷?……我教給你,記著!Flutter 狀態管理應該這樣寫。將來做高階工程師的時候,做架構要用。” 我暗想我和高階工程師的等級還很遠呢,而且我們總監也從不用 Flutter 開發應用;又好笑,又不耐煩,懶懶的答他道,“誰要你教,不就是用一個 setState 方法麼?” 孔乙己顯出極高興的樣子,發了一個 耶的勝利表情,點頭說,“對呀對呀!……狀態管理有N 種寫法,你知道麼?” 我自然是沒有回答,但他自己卻真的列了出來。

Provider

在 Pub 上最受歡迎的狀態管理外掛之一,憑藉簡潔、易用、高效能受到了很多 Flutter 開發者的喜愛,更是成為了官方首要推薦的狀態管理工具。我們在Flutter 入門與實戰(四十):以購物車為例初探狀態管理其實已經介紹過。外掛pub地址:Provider package。本質上,Provider是在 InheritedWidget 基礎上的封裝,使用Provider具有如下特性:

  • 簡化資源的分配和銷燬;
  • 懶載入;
  • 減少了大量建立狀態管理相關類程式碼的工作;
  • 通用的方式去消費 InheritedWidget 共享的資料;
  • 對於複雜度顯著上升的監聽鏈路,提供了高可擴充套件性。

setState

最為初級的狀態管理方法,官方的Hello World示例用的就是這種方式,優點是簡單,缺點嘛——參照其他狀態管理的優點,那些都是針對這種方式的缺點改進的。

InheritedWidget 和 InheritedModel

前面介紹的 ModelBinding就是這種方式,Provider其實也是這種方式。對 InheritedWidget 進行封裝,實現資料在元件樹上傳遞,進而達到狀態資料共享和區域性重新整理的目的。

Redux

類似 React 的狀態管理工具Redux,本質上是一個狀態容器,pub地址:Flutter-Redux package。關鍵在於提供了3種 Widget

  • StoreProvider:基礎 Widget,它會把指定的Redux狀態資料(Redux Store) 傳遞給需要的下級元件;
  • StoreBuilder:一個從 StoreProvider 獲取狀態的下級元件,它會將獲取到的狀態傳遞給一個返回 Widgetbuilder 方法。
  • StoreConnector:一個從最臨近的 StoreProvider 祖先元件獲取狀態的下級元件,然後利用 指定的 converter將狀態轉換為 ViewModel 物件後給到 builder 方法。任何時候,狀態發出一個更改事件後,該元件會被自動重建,從而無需主動管理事件訂閱。

Fish Redux

閒魚出品的一個基於 Redux 的整體應用框架,對於構建大中型應用來說很合適,pub 地址:Fish-Redux package。與 Redux 的區別是,Fish Redux 是一個應用框架,解決了如應用分治、通訊、資料驅動、解耦等問題。作為一個應用框架,優點是可以為團隊建立一套統一的規範,當然缺點也有,比如對於小應用來說可能過於龐大,靈活性不足,可能會影響開閥發效率。

BLoC / Rx

一個基於Stream / Observable 正規化的系列,關於介紹可以看官方的文件:Flutter BLoC

GetIt

GetIt 實際上是一個基於狀態管理的服務管理工具,優點是不需要 BuildContext。如果想使用依賴注入、面向介面程式設計的方式來實現程式碼解耦和應用管理則十分適合。對應的 pub 包和文件如下:

  • GetIt package:基礎的服務管理工具,提供了容器幫助程式碼找到對應的服務提供物件。
  • GetIt Mixin:GetIt 的擴充套件,使得 GetIt 可以完全應用於狀態管理。
  • GetIt Hooks:GetIt 的另一個擴充套件,可以用於 flutter_hooks 的場景。
  • Flutter state management for minimalist:一篇介紹 Flutter 狀態管理與應用架構的文章,值得仔細閱讀。

MobX

基於觀察者模式和響應式模式的狀態管理庫,GitHub 地址:MobX。 MobX 的目標是將應用的介面和響應式資料連線起來。這種方式是完全自動的,而且感覺很自然(類似雙向繫結)。對於開發者而言,只需要關注介面需要消費的響應式資料,而不用擔心保持二者的同步。

Flutter Commands

基於 ValueNotifier,使用命令模式實現的響應式狀態管理庫。最佳的實踐是與 GetIt 結合,也可以使用 Provider或其他容器配合。pub 地址:Flutter Command

Binder

基於 InheritedWidget 的狀態管理包,仿照的是recoil,目標是想將業務、狀態和介面分離解耦,pub 地址:Binder packageimage.png

GetX

一個簡化的狀態管理解決方案,pub 地址:GetX package。GetX 是一個超輕量、但很強大的 Flutter 解決方案,提供了高效能的狀態管理,智慧依賴注入和快速可用的路由管理工具。GetX由於簡化了很多實現程式碼,目前的流行度已經超過了 Provider。

States Rebuilder

States Rebuilder 是高效能,滿足預期和可控的狀態管理工具。支援可變和不可變的狀態,實現了嚴格的狀態控制,並且支援自動清除狀態。而且還可以在 StatelessWidget 中使用 setState(狀態資料模型類的 setState,) 更新介面,同樣也支援無需 BuildContext 的頁面導航和訊息提示。GitHub 地址: States Rebuilder

尾聲

等到孔乙己寫完之後,我竟然有點驚到了,難道這些他都會?但礙於顏面,又不好意思問他。只好自己按照他寫的那些去搜了一下。至於他是不是都會,也就無從知道了!

總結

由於 Dart 語言和 Javascript有很多共同之處,因此在 pub 上有很多類似 Javascript 的庫,譬如 Redux,MobX 等。實際上,沒有最好的狀態管理工具,只有最合適的狀態管理工具。具體如何選擇可以參考以下幾點:

  • 更新維護及時性:Flutter 本身的迭代速度很快,因此有些外掛如果不及時維護的話意味著你之後的程式碼全部需要更改,尤其是狀態管理這類涉及到整個應用架構的外掛。
  • 使用者數量:可以通過 pub 的評分和 Github 的評分來評估使用者的情況,使用人數不多意味著你可能會需要自己踩坑排雷,對於自己玩的話無所謂,但是對於產品開發就可能會影響整個產品的開發進度。
  • 團隊適應性:如果是你一個人開發,那可以忽略這一點,但是如果團隊有多人,那需要考慮一個大家都能夠快速上手的外掛。
  • 原生依賴度:有不少外掛是需要依賴原生的,而有些原生本身就是第三方的開原始碼,如果這些開原始碼停止維護了很可能導致 Flutter 的外掛也無法更新。因此,除非是官方外掛,對於第三方外掛要特別小心,如果第三方外掛依賴於原生甚至是第三方開原始碼,那麼就需要注意要慎重選擇。如果可以,儘可能選擇純 Dart 的外掛。

我是島上碼農,微信公眾號同名,這是Flutter 入門與實戰的專欄文章。

??:覺得有收穫請點個贊鼓勵一下!

?:收藏文章,方便回看哦!

?:評論交流,互相進步!

相關文章