This article is from Medium written by Jorge Coca, Thank you Jorge for allowing me translate your awesome article into Chinesereact
本文來源於Medium,由Jorge Coca撰寫,並准許我翻譯成中文git
狀態管理在Flutter中是一個很熱的話題。可選的方案有不少,這可能很好,但卻很容易陷入其中,在項目中選擇最適合方案時感到迷失。我也是,不過我已經找到了適合個人方案,讓我來分享給你。github
爲了找到適合需求的方案,頭一件事就是確認需求,而後設置目標和指望。對我而言,我定義了以下:redux
在給定了這些限制後,咱們來看看咱們可選的方案:設計模式
在深刻分析不一樣方案前,有一件事可能會幫助咱們更好的理解怎樣選擇——什麼是局部狀態,什麼是全局狀態安全
爲了這件事,咱們來考慮一件事:想象一個簡單的登錄表單,用戶能夠輸入用戶名和密碼,若是登錄成功,就能夠從後臺得到到id。在這個例子中,登陸表單的任何驗證類型,均可以考慮爲局部狀態,由於這些規則僅適用於這個組件,而App的其餘部分不須要知道這個類型。可是從後臺獲取的id,就須要考慮成全局狀態,由於它影響整個app的做用域(未登陸和已登錄),並且可能別的組件會依賴它。bash
若是你不想等過久,或者對深刻探索不感興趣,下面這個表能夠快速告訴你個人發現:架構
個人建議是:使用BLoC進行局部狀態管理,使用Redux進行全局狀態管理。特別是對持續迭代的複雜應用而言。app
快速製做原型的時候,在widget中使用setState()很是爽,並且你會當即獲得反饋。可是這並不能幫助咱們實現目標:展現邏輯和業務邏輯在同一個類裏,打破了乾淨和高質量代碼的原則。之後應用的規模擴張的時候,代碼的維護將會是一個挑戰。所以除了快速原型設計,我不建議使用setState()。less
ScopedModel是Brian Egan維護的第三方包。它讓咱們建立Model對象,而後在咱們須要的時候調用notifyListeners();例如,在咱們的模型(model)屬性改變的時候:
class CounterModel extends Model {
int _counter = 0;
int get counter = _counter;
void increment() {
_counter++;
notifyListeners();
}
}
複製代碼
在咱們的widget中,咱們可使用ScopedModelDescendant來響應模型的變化:
class CounterApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new ScopedModel<CounterModel>(
model: new CounterModel(),
child: new Column(children: [
new ScopedModelDescendant<CounterModel>(
builder: (context, child, model) => new Text('${model.counter}'),
),
new Text("Another widget that doesn't depend on the CounterModel")
])
);
}
}
複製代碼
和setState()相反,若是咱們使用ScopedModel,就能夠分離展現邏輯和業務邏輯,這樣就很好了。可是也會有一些侷限:
綜上,除非狀態很容易控制,不然我不建議你使用ScopedModel;若是你的應用足夠複雜,我不相信這是支持複雜性和迭代的正確答案。
BLoC是一個被Google創造並使用的設計模式;他會幫助咱們完成這幾件事:
BLoC背後的想法很簡單:
Sink<I>
API來描述咱們組件的異步輸入Stream<T>
API來描述咱們組件的異步輸出StreamBuilder
widget來管理數據流,咱們不須要再維護對數據流的訂閱和widget的重繪由於它被Google重度使用和推薦,他們有個很是好的例子:github.com/filiph/stat…
即便是全局狀態管理,我相信它也會有很好的解決;可是你將會在這個領域面臨一些挑戰,例如怎麼在不一樣UI組件中插入BLoC更合適,我想這是Redux的閃光點。
在文章的開頭,其中一個目標就是找到一個能夠普遍應用而且可預期的方案。好吧,就是Redux。
Redux是一個設計模式,融合了一些工具,來幫助咱們管理全局狀態。它創建在3個基本原則上:
Redux是網頁開發着普遍使用的設計模式(譯者注:好比用在React.js中),因此在移動端也有普遍的基礎,會讓咱們互相收益。
Brian Egan維護redux和flutter_redux,並且創造了一個很是棒的ToDo 應用, 集成了不少不一樣的架構模式,包括Redux。
鑑於Redux的全部特性,我徹底建議使用它來管理全局狀態,可是若是你想擴張你的應用,請確保在Redux架構裏面不包含局部狀態。
這裏並無正確與錯誤答案。爲了選一個工具,或者應用一個設計模式,理解你本身的需求很是重要。對我和個人需求來講,Redux和BLoC搭配能幫助我快速安全地擴張個人應用。同時由於工具的可用性被社區很好地理解,更多的開發者開始使用它。話說回來,每一個人都有不一樣的需求和看問題的角度,重要的是始終有好奇心,去學習和思考,什麼纔是最好的方案
你能夠訪問原做者的GitHub
也歡迎關注個人更多文章,以及個人GitHub