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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C语言零基础入门篇 - 6】:数组、字符和字符串带你探索无限可能

文章目录 数组一维数组一维数组的定义一维数组的初始化 字符数组二维数组二维数组存汉字 字符串相关函数小结 数组 特点: 在同一个数组中,所有元素都是同一个类型。可以是int、char、float、double等类型。数组是一种构造类型,是一批数据的…

PCIe进阶之TL:Completion Rules TLP Prefix Rules

1 Completion Rules & TLP Prefix Rules 1.1 Completion Rules 所有的 Read、Non-Posted Write 和 AtomicOp Request 都需要返回一个 Completion。Completion 有两种类型:一种带数据负载的,一种不带数据负载的。以下各节定义了 Completion header 中每个字段的规则。 C…

腾讯百度阿里华为常见算法面试题TOP100(3):链表、栈、特殊技巧

之前总结过字节跳动TOP50算法面试题: 字节跳动常见算法面试题top50整理_沉迷单车的追风少年-CSDN博客_字节算法面试题 链表 160.相交链表

基于python+django+vue的外卖管理系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于pythondjangovueMySQL的外…

word文档无损原样转pdf在windows平台使用python调用win32com使用pip安装pywin32

前提: windows环境下,并且安装了office套装,比如word,如果需要调用excel.也需要安装。在另外的文章会介绍。这种是直接调用word的。所以还原度会比较高。 需求: word文档转pdf,要求使用命令行形式,最终发布为api接口…

通过sshd_config限制用户登录

在CentOS Stream或其他现代的Linux发行版中,你可能会发现传统的hosts.deny和 hosts.allow文件已经不存在或不被使用。这是因为随着时间的推移,系统的安全策略和网络管理工具已经发生了演变,许多系统管理员和发行版维护者选择使用更现代、更灵…

鸿蒙next web组件和h5 交互实战来了

前言导读 鸿蒙next web组件这个专题之前一直想讲一下 苦于没有时间,周末把代码研究的差不多了,所以就趁着现在这个时间节点分享给大家。也希望能对各位读者网友工作和学习有帮助,废话不多说我们正式开始。 效果图 默认页面 上面H5 下面ArkU…

小米,B站网络安全岗位笔试题目+答案

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

开源免费的工贸一体行业ERP管理系统

引言 在当今数字化浪潮汹涌澎湃的时代,中小企业面临着前所未有的挑战与机遇。如何实现数字化转型发展,成为了众多中小企业主心头的大事。 据相关数据显示,目前我国中小企业数量已经超过了 4000 万户,然而成功实现数字化转型的比例…

.NET 一款免杀的白名单工具可执行系统命令

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

使用Mockito进行单元测试

1、单元测试介绍 Mockito和Junit是用于单元测试的常用框架。单元测试即:从最小的可测试单元(如函数、方法或类)开始,确保每个单元都能按预期工作。单元测试是白盒测试的核心部分,它有助于发现单元内部的错误。 单元测试…

【AcWing 158周赛】

5842. 拆树 主要思路: 如何分割? 深度遍历,当遍历的子数的sum为总sum的三分之一即是一个分割方法。 1其中要注意节点范围为 [ − 100 , 100 ] [-100,100] [−100,100],所以当 总树 s u m 0 总树sum0 总树…

算法:30.串联所有单词的子串

题目 链接:leetcode链接 思路分析(滑动窗口) 这道题目类似寻找异位词的题目,我认为是寻找异位词的升级版 传送门:寻找异位词 为什么说像呢? 注意:这道题目中words数组里面的字符串长度都是相同的&…

C语言-数据结构 弗洛伊德算法(Floyd)邻接矩阵存储

弗洛伊德算法相比迪杰斯特拉相似的地方都是遍历邻接矩阵不断调整最短路径的信息,并且两种算法面对多源最短路径的时间复杂度都是O(n^3),Floyd采用的是动态规划而Dijkstra是采用贪心的思想。在Floyd中我们将创建两个数组进行辅助,一个path二维…

sqlgun靶场训练

1.看到php?id ,然后刚好有个框,直接测试sql注入 2.发现输入1 union select 1,2,3#的时候在2处有回显 3.查看表名 -1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schemadatabase()# 4.查看列名…

磁盘写入缓存区太大,如何清理C盘缓存

针对“磁盘写入缓存区太大,如何清理C盘缓存”的问题,我们可以从多个角度进行专业解答。首先,需要明确的是,“磁盘写入缓存区太大”这一表述可能涉及硬盘缓存的设置或系统缓存管理,但通常用户面对的问题更多是关于C盘空…

极速上云2.0范式:一键智连阿里云

在传统上云的现状与挑战: 专线上云太重,VPN上云不稳,云上VPC,云下物理网络,多段最后一公里...... 层层对接,跳跳延迟,好生复杂! 当你试图理解SD-WAN供应商和阿里云的文档,以协调路由…

【23-24年】年度总结与迎新引荐

文章目录 相关连接前言1 忙碌的备研与本科毕设2 暑期阿里之旅3 团队荣誉与迎新引荐4 项目合作意向 相关连接 个人博客:issey的博客 - 愿无岁月可回首 前言 自从2023年4月更新了两篇关于NLP的文章后,我便消失了一年半的时间。如今,随着学业…

[000-01-008].第05节:OpenFeign特性-重试机制

我的后端学习大纲 SpringCloud学习大纲 1.1.重试机制的默认值: 1.重试机制默认是关闭的,给了默认值 1.2.测试重试机制的默认值: 1.3.开启Retryer功能: 1.修改配置文件YML的配置: 2.新增配置类: packa…

STM32启用FPU浮点运算

这篇文章产生背景:其他人的文章太杂了,对我这种菜鸡无法接受; 参考文章: stm32h743单片机嵌入式学习笔记7-FPU_stmh743vit4-CSDN博客 stm32F407 打开 FPU(浮点运算处理器)_stm32f407开启fpu-CSDN博客 STM32F4CubeMXHal库下使能…