kotlin kmp 副作用函數 effect

在 Kotlin Multiplatform (KMP) Compose 中,“effect functions”(或“effect handlers”)是專門的可組合函數,用于在 UI 中管理副作用。

在 Compose 中,可組合函數應該是“純”的和聲明式的。這意味著它們應該理想地只接受輸入并生成 UI,而不引起其作用域之外的任何變化。然而,現實世界中的應用程序通常需要與“外部世界”進行交互,例如:

  • 網絡請求:從 API 獲取數據。
  • 數據庫操作:保存或加載數據。
  • 日志/分析:將數據發送到外部服務。
  • 管理生命周期依賴的資源:注冊/注銷監聽,器管理訂閱。
  • 觸發一次性 UI 事件:顯示一個 Snackbar,導航到另一個屏幕。
  • 更新非 Compose 狀態:與 ViewModel 或其他非 Compose 狀態持有者交互。

這些操作被稱為“副作用”,因為它們改變了應用程序在即時 UI 渲染過程之外的狀態。如果處理不當,它們可能會導致不可預測的行為、錯誤或性能問題。

為什么需要 Effect Functions?

Compose 的重組模型意味著可組合函數可能會頻繁且以任意順序被調用。如果將副作用直接放入普通的可組合函數中,它們可能會被重復執行或在不適當的時間執行,從而導致問題。Effect functions 提供了一種受控且具有生命周期感知能力的方式來執行這些副作用。

KMP Compose 中最常見的 effect functions:

  1. LaunchedEffect
  • 用途:啟動一個與可組合生命周期綁定的協程(異步操作),并依賴于一組“keys”。
  • 何時使用:當需要在可組合進入組合時執行掛起函數(例如,網絡請求、數據庫調用),或者當特定“key”(狀態變量或參數)發生變化時。如果 key 發生變化,LaunchedEffect 啟動的前一個協程將自動取消,并啟動一個新的協程。
  • 示例代碼:
    @Composablefun UserProfileScreen(userId: String) {var userData by remember { mutableStateOf<UserData?>(null) }LaunchedEffect(key1 = userId) {userData = fetchUserData(userId)}if (userData != null) {Text(text = "Name: ${userData?.name}")Text(text = "Email: ${userData?.email}")} else {CircularProgressIndicator()}}suspend fun fetchUserData(userId: String): UserData {// 模擬網絡請求delay(1000)return UserData(name = "John Doe", email = "john.doe@example.com")}data class UserData(val name: String, val email: String)```2. DisposableEffect- 用途:執行與可組合生命周期和 keys 相關聯的設置和清理操作。
- 何時使用:當需要管理需要顯式清理的資源時。它提供了一個 onDispose 塊,當可組合離開組合或者其 keys 發生變化時(意味著 effect 被“處置”,可能會設置一個新的 effect)執行。
- 示例代碼:

@Composable
fun LocationScreen() {
var location by remember { mutableStateOf<String?>(null) }

    DisposableEffect(Unit) {val listener = object : LocationListener {override fun onLocationChanged(loc: Location) {location = "${loc.latitude}, ${loc.longitude}"}}// 注冊監聽器registerLocationListener(listener)onDispose {// 注銷監聽器unregisterLocationListener(listener)}}if (location != null) {Text(text = "Current Location: $location")} else {Text(text = "No location available")}
}
  1. SideEffect
  • 用途:在可組合函數成功重組時運行非掛起代碼。

  • 何時使用:在成功重組后,將 Compose 狀態與外部、非 Compose 管理的對象同步。它確保代碼在 UI 更新后運行。

  • 示例代碼:

    @Composable
    fun LoggingScreen() {
    var counter by remember { mutableStateOf(0) }

      SideEffect {log("Counter value is now $counter")}Button(onClick = { counter++ }) {Text(text = "Increment")}
    

    }

    fun log(message: String) {
    println(“LOG: $message”)
    }```

  1. rememberCoroutineScope
  • 用途:獲取一個與可組合生命周期綁定的 CoroutineScope。

  • 何時使用:當需要從 Compose 作用域之外的回調(例如,Button 的 onClick lambda)中啟動協程,但仍然希望當可組合離開組合時取消協程。可以在回調中手動調用 .launch { … }。

  • 示例代碼:

    @Composable
    fun DelayedActionScreen() {
    var message by remember { mutableStateOf<String?>(null) }
    val scope = rememberCoroutineScope()

      Button(onClick = {scope.launch {delay(2000)message = "Action completed after 2 seconds"}}) {Text(text = "Perform Delayed Action")}if (message != null) {Text(text = message!!)}
    

    }

  1. produceState
  • 用途:將非 Compose 可觀察狀態(例如,基于回調的 API,Android 中的 Flow 或 LiveData)轉換為 Compose State,以便其他可組合函數可以觀察它。
  • 何時使用:當需要將現有的命令式 API 或數據流集成到 Compose UI 中時。它啟動一個協程來隨時間更新 State。
  • 示例代碼:
 @Composablefun DataScreen() {val data = produceState(initialValue = "Loading...") {val flow = fetchDataFlow()collect {value = it}}Text(text = data.value)}fun fetchDataFlow(): Flow<String> {return flow {delay(1000)emit("Data loaded")}}```6. derivedStateOf- 用途:從其他 State 對象創建一個 State,但只有當派生值實際發生變化時才會重組,而不是只要底層狀態發生變化就重組。
- 何時使用:當基于其他狀態有復雜的計算或轉換,并且只想在派生值的結果發生變化時才觸發重組時,用于性能優化。
- 示例代碼:
@Composable
fun DerivedStateScreen() {var x by remember { mutableStateOf(0) }var y by remember { mutableStateOf(0) }val derivedState = derivedStateOf {x + y}Text(text = "Derived State: ${derivedState.value}")Button(onClick = { x++ }) {Text(text = "Increment x")}Button(onClick = { y++ }) {Text(text = "Increment y")}
}

7. snapshotFlow- 用途:將 Compose State 對象轉換為 Kotlin Flow。
- 何時使用:當想利用 Kotlin Flows 的強大功能(例如,map、filter、debounce 等操作符)與 Compose State 時。
- 示例代碼:

@Composable
fun DebouncedSearchScreen() {
var query by remember { mutableStateOf(“”) }

    val flow = snapshotFlow { query }.debounce(300).collect { performSearch(it)}TextField(value = query, onValueChange = { query = it })
}fun performSearch(query: String) {println("Performing search for: $query")
}

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

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

相關文章

3.3.1_1 檢錯編碼(奇偶校驗碼)

從這節課開始&#xff0c;我們會探討數據鏈路層的差錯控制功能&#xff0c;差錯控制功能的主要目標是要發現并且解決一個幀內部的位錯誤&#xff0c;我們需要使用特殊的編碼技術去發現幀內部的位錯誤&#xff0c;當我們發現位錯誤之后&#xff0c;通常來說有兩種解決方案。第一…

【Pandas】pandas DataFrame isna

Pandas2.2 DataFrame Missing data handling 方法描述DataFrame.fillna([value, method, axis, …])用于填充 DataFrame 中的缺失值&#xff08;NaN&#xff09;DataFrame.backfill(*[, axis, inplace, …])用于**使用后向填充&#xff08;即“下一個有效觀測值”&#xff09…

MQTT協議:物聯網時代的通信基石

MQTT協議&#xff1a;物聯網時代的通信基石 在當今快速發展的物聯網&#xff08;IoT&#xff09;時代&#xff0c;設備之間的通信變得尤為重要。MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;協議作為一種輕量級的消息傳輸協議&#xff0c;正逐漸成為物聯…

Excel 表格內批量添加前綴與后綴的實用方法

我們經常需要為 Excel 表格中的內容統一添加前綴或后綴&#xff0c;例如給編號加“NO.”、給姓名加“會員_”等。手動操作效率低&#xff0c;本文將介紹幾種實用的方法&#xff0c;幫助你快速完成批量添加前綴和后綴的操作。 使用“&”運算符添加前綴或后綴&#xff08;推…

uniapp 實現騰訊云IM群文件上傳下載功能

UniApp 集成騰訊云IM實現群文件上傳下載功能全攻略 一、功能背景與技術選型 在團隊協作場景中&#xff0c;群文件共享是核心需求之一。本文將介紹如何基于騰訊云IMCOS&#xff0c;在uniapp中實現&#xff1a; 群內文件上傳/下載文件元數據管理下載進度追蹤跨平臺文件預覽 二…

GO協程(Goroutine)問題總結

在使用Go語言來編寫代碼時&#xff0c;遇到的一些問題總結一下 [參考文檔]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函數默認的Goroutine 場景再現&#xff1a; 今天在看到這個教程的時候&#xff0c;在自己的電…

uniapp微信小程序視頻實時流+pc端預覽方案

方案類型技術實現是否免費優點缺點適用場景延遲范圍開發復雜度?WebSocket圖片幀?定時拍照Base64傳輸? 完全免費無需服務器 純前端實現高延遲高流量 幀率極低個人demo測試 超低頻監控500ms-2s???RTMP推流?TRTC/即構SDK推流? 付費方案 &#xff08;部分有免費額度&#x…

分布式鎖實戰:Redisson vs. Redis 原生指令的性能對比

分布式鎖實戰&#xff1a;Redisson vs. Redis 原生指令的性能對比 引言 在DIY主題模板系統中&#xff0c;用戶可自定義聊天室的背景、圖標、動畫等元素。當多個運營人員或用戶同時修改同一模板時&#xff0c;若沒有鎖機制&#xff0c;可能出現“甲修改了背景色&#xff0c;乙…

C++ 設計模式《復制粘貼的奇跡:小明的原型工廠》

&#x1f468;?&#x1f393; 模式名稱&#xff1a;原型模式&#xff08;Prototype Pattern&#xff09; &#x1f4d6; 背景故事 創業初期&#xff0c;小明每天加班寫配送路線、配送策略、營銷套餐。可當業務做大后&#xff0c;他發現大家常常下單“上次那個套餐”—— “老…

【Elasticsearch】映射:fielddata 詳解

映射&#xff1a;fielddata 詳解 1.fielddata 是什么2.fielddata 的工作原理3.主要用法3.1 啟用 fielddata&#xff08;通常在 text 字段上&#xff09;3.2 監控 fielddata 使用情況3.3 清除 fielddata 緩存 4.使用場景示例示例 1&#xff1a;對 text 字段進行聚合示例 2&#…

開源 vGPU 方案:HAMi,實現細粒度 GPU 切分

本文主要分享一個開源的 GPU 虛擬化方案&#xff1a;HAMi&#xff0c;包括如何安裝、配置以及使用。 相比于上一篇分享的 TimeSlicing 方案&#xff0c;HAMi 除了 GPU 共享之外還可以實現 GPU core、memory 得限制&#xff0c;保證共享同一 GPU 的各個 Pod 都能拿到足夠的資源。…

PlayDiffusion上線:AI語音編輯進入“無痕時代”

在語音合成與語音編輯領域&#xff0c;一個長期存在的挑戰是如何在修改語音內容的同時&#xff0c;保持原始語音的自然性、連貫性和說話人特征。近日&#xff0c;一款名為 PlayDiffusion 的新型 AI 語音修復模型應運而生&#xff0c;成功實現了這一目標。 PlayDiffusion 是一個…

2025年能源電力系統與流體力學國際會議 (EPSFD 2025)

2025年能源電力系統與流體力學國際會議&#xff08;EPSFD 2025&#xff09;將于本年度在美麗的杭州盛大召開。作為全球能源、電力系統以及流體力學領域的頂級盛會&#xff0c;EPSFD 2025旨在為來自世界各地的科學家、工程師和研究人員提供一個展示最新研究成果、分享實踐經驗及…

微信小程序前端面經

一、技術棧與編碼能力&#xff08;10min&#xff09; 1. Vue 3 & Composition API Q1&#xff1a;請解釋一下 ref 和 reactive 的區別&#xff1f;你在項目中是如何使用的&#xff1f; 答&#xff1a;ref是包裝一個原始值或對象&#xff0c;通過.value訪問&#xff0c;r…

rknn toolkit2搭建和推理

安裝Miniconda Miniconda - Anaconda Miniconda 選擇一個 新的 版本 &#xff0c;不用和RKNN的python版本保持一致 使用 ./xxx.sh進行安裝 下面配置一下載源 # 清華大學源&#xff08;最常用&#xff09; conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…

WordPress插件:AI多語言寫作與智能配圖、免費AI模型、SEO文章生成

厭倦手動寫WordPress文章&#xff1f;AI自動生成&#xff0c;效率提升10倍&#xff01; 支持多語言、自動配圖、定時發布&#xff0c;讓內容創作更輕松&#xff01; AI內容生成 → 不想每天寫文章&#xff1f;AI一鍵生成高質量內容&#xff01;多語言支持 → 跨境電商必備&am…

Houdini POP入門學習07 - 分組

使用PopGroup可對粒子進行分組操作&#xff0c;并通過表達式從而更靈活的處理粒子行為。 1.創建box作為發射器&#xff0c;連接popnet節點。 2.雙擊進入popnet&#xff0c;添加popwind添加向上風力。現在播放粒子可見粒子向上方移動。 3.添加popgroup進行分組&#xff0c;開啟…

機器學習復習3--模型評估

誤差與過擬合 我們將學習器對樣本的實際預測結果與樣本的真實值之間的差異稱為&#xff1a;誤差&#xff08;error&#xff09;。 誤差定義&#xff1a; ①在訓練集上的誤差稱為訓練誤差&#xff08;training error&#xff09;或經驗誤差&#xff08;empirical error&#x…

Docker 鏡像上傳到 AWS ECR:從構建到推送的全流程

一、在 EC2 實例中安裝 Docker&#xff08;適用于 Amazon Linux 2&#xff09; 步驟 1&#xff1a;連接到 EC2 實例 ssh -i your-key.pem ec2-useryour-ec2-public-ip步驟 2&#xff1a;安裝 Docker sudo yum update -y sudo amazon-linux-extras enable docker sudo yum in…

MobileNet 改進:基于MobileNetV2和SSPP的圖像分類

1.創新點分析 在計算機視覺領域,高效的圖像分類模型一直是研究熱點。 本文將詳細解析一個結合了MobileNetV2和空間金字塔池化(SSPP)的深度學習模型實現。 模型概述 這個代碼實現了一個輕量級但功能強大的圖像分類器,主要包含兩個核心組件: MobileNetV2作為特征提取器 自定…