Flutter 狀態管理 Provider

狀態管理必要性

Flutter基于聲明式構建UI,原生則是命令式,狀態管理是用于解決聲明式開發帶來的問題。

例:命令式的原生,數據更新需要拿到對應控件并更改其顯示值;而聲明式則需要更改數據值并通過setstate更新狀態,重新構建組件

Flutter 中有這么一種說法: UI = f(state):

聲明式的優勢

  • 優勢:

  • 無需繁瑣地控制組件,只需聚焦于狀態管理,負責狀態—>UI的映射

  • 劣勢:

  • 邏輯和頁面UI耦合,導致無法復用/單元測試、修改混亂等:MVVM等架構解決

  • 跨頁面訪問數據

  • 控制頁面刷新范圍

provider工作原理

provider內部為DelegateWidget(委托組件)是一個StatefulWidget,可更新,具有生命周期,借助各種代理完成
狀態共享使用InheritedProvider這個InheritedWidget實現
通過MultiProvider和Consumer封裝,對組合與刷新顆粒度控制

provider工作流程:

設置到changeNotifierProvider的changeNotifier被執行addListener添加監聽listener
listener內會調用StateDelegate的StateSetter方法,從而調用到StatefulWidget的setState
在changeNotifier執行notifyListeners時,最終觸發setState更新

provider異同

  • ListenableProvider / ChangeNotifierProvider

ListenableProvider提供的對象是繼承了Listenable抽象類的子類,只能通過繼承來實現addListener/removeListener方法,手動管理收聽者

changeNotifier實現了Listenable,而混入了changeNotifier的類自動實現了監聽管理

ChangeNotifierProvider 和 ListenableProvider 究竟區別在哪呢,ChangeNotifierProvider 會在你需要的時候,自動調用其 _disposer 方法。

  • ValueListenableProvider,提供了繼承/混入/實現了ValueListenable的model,專門用于只有一個單一變化數據的ChangeNotifier,通過ValueListenable處理的類不再需要數據更新時調用notifyListeners。

  • StreamProvider,專門提供一條Single Stream,提供了方法捕獲異常、更新數據、構建流、構建流控制器等

狀態同步

  • 獲取頂層數據:flutter在每個element上維護一個InheritedWidget哈希表來向下傳遞element樹中的信息,通常情況下,多個element引用相同的哈希表,并且該表僅在element引入新的InheritedWidget時改變, 時間復雜度為O(1)。
  • 通知刷新:listener模式,model中維護聽眾,并通過notifiedListener通知刷新,全局狀態需放在頂層之上,優先初始化

數據初始化

  • 全局數據:main方法執行,保證只執行一次
  • 單頁面數據:StatefulWidget中的InitState中不可執行Provider.of(context),當監聽后,在notifyListeners的時候,會觸發context所對應的State的[State.build]和[State.didChangeDependencies]方法,數據到來時又會觸發下一次請求,無限請求下去。

解決頁面和邏輯的耦合

思路:

  • 通過flutter樹機制解決,如provider
  • 通過依賴注入,如Get

通過flutter樹機制處理V—>P的獲取

flutter三棵樹:widget、element、render object

widget樹是虛擬結構,只是描述組件嵌套關系,但element和renderObject在運行時實際存在。element組件中包含了_parent屬性,存放其父節點element,而其又實現了buildContext接口,包含了對樹結構操作的方法

原本應該是通過context.findAncestorStateOfType向上獲取父組件的信息,在有了provider之后通過provider.of(context)向上獲取頂層provider組件中的presenter對象

通過依賴注入解決V—>P的獲取

擺脫context依賴,基于get借助一個全局單例的map存儲對象,通過依賴注入的方式,實現對Presenter層的獲取,使得可在任意類中獲取到Presenter

map對應的key是runtimeType+tag,其中tag為可選參數,value對應object

get也可解決跨頁面訪問數據

避免setstate全局更新

觀察者模式,局部更新

  • ValueNotifier、ValueListenableBuilder
  • ChangeNotifierProvider、ChangeNotifier、Consumer:從頂層ChangeNotifierProvider獲取存儲的ChangeNotifier,Consumer作為子組件獲取對應數據

Get對應方式則是Get.put和GetBuilder,Get.put提前存儲數據對象,為GetBuilder組件指定數據類型作為泛型,因為Get基于單例,所以GetBuilder可以直接通過泛型獲取到存入的對象,在builder方法中暴露,使得組件和數據建立了監聽關系,并在數據更新后只驅動將其作為泛型的GetBuilder組件更新

使用缺陷

  • provider的context層級過高,如provider傳入的context是根層級的,而provider在element樹中是根層級下面

解決:對應組件外嵌套一層builder,拿到該結點對應的context / provider作為根結點

  • Get全局單例
    Get全局單例默認以runtimeType為key進行對象存儲,而不同詳情頁實例對應的是同一個class,key值一樣,不添加tag參數,在Get.find時會獲取到已經存儲的對象,即數據混淆了。
    Get存儲的對象也得回收,dipose時進行delete或者使用Get中提供的組件,如GetBuilder,會在dispose中釋放

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/35099.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/35099.shtml
英文地址,請注明出處:http://en.pswp.cn/news/35099.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

sql高頻面試題-連續完成兩個指定動作的用戶統計

用戶行為分析 業務背景 某購物APP最近上線了一個新功能,用戶簽到后可以跳轉到大轉盤抽獎,抽獎獲得的獎金可以抵消購物的費用,以此來培養用戶使用app的習慣。 數據表介紹 現有一張用戶行為表action_log,主要字段如下&#xff0c…

springboot mongodb 配置多數據源

我想要的效果是,一個類統一管理多數據源,我傳個參數進去,它就能返回我對應的mongotemplate 但是根據"mongbodb 多數據源"的關鍵詞,找不到我想要的效果。 網上大多都是明確知道自己是幾個數據源,然后每個數…

Styletron: 面向組件的樣式設計工具包

styletron官網: styletron的GitHub鏈接: styletron-react 一. 介紹 Styletron是一個通用的component-oriented(面向組件的)樣式工具。它屬于css-in-js類別。Styletron可以很好地與React配合使用,但也可以與其他框架或…

docker復現nginx錯誤配置漏洞

目錄 一、nginx環境搭建 1.1搭建步驟 二、docker復現Nginx配置漏洞 2.1安裝docker 2.2復現過程 2.1CRLF(carriage return/line feed)注入漏洞 2.2.目錄穿越 一、nginx環境搭建 1.1搭建步驟 1.先創建Nginx的目錄并進入(命令如下) mkdir /soft &&…

Android Framework底層原理之WMS的啟動流程

一 概述 今天,我們介紹 WindowManagerService(后續簡稱 WMS)的啟動流程,WMS 是 Android 系統中,負責窗口顯示的的服務。在 Android 中它也起著承上啟下的作用。 如下圖,就是《深入理解 Android》書籍中的…

033_小馳私房菜_Qcom平臺8系列-Dump Jpeg Jpeg Exif信息修改

全網最具價值的Android Camera開發系列資料~ 作者:8年Android Camera開發,從Camera app一直做到Hal和驅動~ 歡迎訂閱,相信能擴展你的知識面,提升個人能力~ 平臺:高通8系列 jpeg相關代碼邏輯在camx/src/swl/jpeg/ 路徑下 一、Dump Jpeg 有時我們想把hal這邊拍照的jpe…

【C++】STL初識

1.STL的基本概念 2.vector存放內置數據類型 #include <iostream> using namespace std; #include <vector> #include <algorithm>void MyPrint(int val) {cout << val << endl; }void test01() {//創建vector容器對象&#xff0c;并且通過模板參…

Harbor企業鏡像倉庫部署(本地)

簡述&#xff1a; Docker 官方鏡像倉庫是用于管理公共鏡像的地方&#xff0c;大家可以在上面找到想要的鏡像&#xff0c;也可以把自己的鏡像推送上去。但是有時候服務器無法訪問互聯網&#xff0c;或者不希望將自己的鏡像放到互聯網上&#xff0c;那么就需要用到 Docker Regis…

越南的區塊鏈和NFT市場調研

越南的區塊鏈和NFT市場調研 基本介紹 https://zh.wikipedia.org/wiki/%E8%B6%8A%E5%8D%97 語言文字&#xff1a; 越南語&#xff0c; 文字以國語字&#xff08;越南羅馬字&#xff09;為主&#xff0c;漢喃文&#xff08;漢字&#xff09; 貨幣&#xff1a;越南盾 人口(2022…

Leetcode-每日一題【劍指 Offer 15. 二進制中1的個數】

題目 編寫一個函數&#xff0c;輸入是一個無符號整數&#xff08;以二進制串的形式&#xff09;&#xff0c;返回其二進制表達式中數字位數為 1 的個數&#xff08;也被稱為 漢明重量).&#xff09;。 提示&#xff1a; 請注意&#xff0c;在某些語言&#xff08;如 Java&…

如何安全地移動WSL 2 到另一個驅動器

當您擁有小型 SSD 并且適用于 Linux 的 Windows 子系統 (WSL) 的大小呈指數增長時&#xff0c;這真的很痛苦。沒有簡單的方法將 WSL 安裝移動到另一個驅動器。在這篇博客中&#xff0c;我將討論如何通過小步解決這個問題。 1.打開具有管理員訪問權限的 PowerShell或命令提示符…

【Docker】Windows下docker環境搭建及解決使用非官方終端時的連接問題

目錄 背景 Windows Docker 安裝 安裝docker toolbox cmder 解決cmder 連接失敗問題 資料獲取方法 背景 時常有容器方面的需求&#xff0c;經常構建調試導致測試環境有些混亂&#xff0c;所以想在本地構建一套環境&#xff0c;鏡像調試穩定后再放到測試環境中。 Windows …

多線程與高并發--------線程池

線程池 一、什么是線程池 在開發中&#xff0c;為了提升效率的操作&#xff0c;我們需要將一些業務采用多線程的方式去執行。 比如有一個比較大的任務&#xff0c;可以將任務分成幾塊&#xff0c;分別交給幾個線程去執行&#xff0c;最終做一個匯總就可以了。 比如做業務操…

Windows電腦快速搭建FTP服務教程

FTP介紹 FTP&#xff08;File Transfer Protocol&#xff09;是一種用于在計算機網絡上進行文件傳輸的標準協議。它提供了一種可靠的、基于客戶端-服務器模型的方式來將文件從一個主機傳輸到另一個主機。在本文中&#xff0c;我將詳細介紹FTP的工作原理、數據傳輸模式以及常見…

數據結構【第4章】——棧與隊列

隊列是只允許在一端進行插入操作、而在另-端進行刪除操作的線性表。 棧 棧與隊列&#xff1a;棧是限定僅在表尾進行插入和刪除操作的線性表。 我們把允許插入和刪除的一端稱為棧頂&#xff08;top&#xff09;&#xff0c;另一端稱為棧底&#xff08;bottom&#xff09;&…

VBA技術資料MF42:VBA_從Excel中上面的單元格復制公式

【分享成果&#xff0c;隨喜正能量】唯有夢想才配讓你不安&#xff0c;唯有行動才能解除你的不安.繩鋸木斷&#xff0c;水滴石穿。也許你現在做的事情很小&#xff0c;只要你能日積月累的堅持下去&#xff0c;才會發現意義非凡。所謂的成功&#xff0c;便是別人失敗的時候你還在…

微服務與Nacos概述-2

微服務間消息傳遞 微服務是一種軟件開發架構&#xff0c;它將一個大型應用程序拆分為一系列小型、獨立的服務。每個服務都可以獨立開發、部署和擴展&#xff0c;并通過輕量級的通信機制進行交互。 應用開發 common模塊中包含服務提供者和服務消費者共享的內容 provider模塊是…

10-1_Qt 5.9 C++開發指南_Data Visualization實現數據三維顯示

Data Visualization 是 Qt 提供的用于數據三維顯示的模塊。在 Qt 5.7 以前只有商業版才有此模塊&#xff0c;而從Qt5.7 開始此模塊在社區版本里也可以免費使用了。Data Visualization 用于數據的三維顯示&#xff0c;包括三維柱狀圖、三維空間散點、三維曲面等。Data Visualiza…

鑒源實驗室丨汽車網絡安全攻擊實例解析(二)

作者 | 田錚 上海控安可信軟件創新研究院項目經理 來源 | 鑒源實驗室 社群 | 添加微信號“TICPShanghai”加入“上海控安51fusa安全社區” 引言&#xff1a;汽車信息安全事件頻發使得汽車行業安全態勢愈發緊張。這些汽車網絡安全攻擊事件&#xff0c;輕則給企業產品發布及產品…

高效數據傳輸:輕松上手將Kafka實時數據接入CnosDB

本篇我們將主要介紹如何在 Ubuntu 22.04.2 LTS 環境下&#xff0c;實現一個KafkaTelegrafCnosDB 同步實時獲取流數據并存儲的方案。在本次操作中&#xff0c;CnosDB 版本是2.3.0&#xff0c;Kafka 版本是2.5.1&#xff0c;Telegraf 版本是1.27.1 隨著越來越多的應用程序架構轉…