• 谈谈Android Jetpack Compose中的状态提升


    谈谈Android Jetpack Compose中的状态提升

    在本文中,我们将了解Jetpack Compose中的状态提升(State Hoisting)。在深入研究这个主题之前,让我们先了解一下Jetpack Compose中的有状态(Stateful)和无状态(Stateless)组合。

    有状态 vs 无状态(Stateful Vs Stateless)

    使用remember保存对象的组合会创建内部状态,使其成为有状态(Stateful)组合。

    无状态组合是指不保存任何状态的组合。通过使用状态提升(State Hoisting)可以轻松实现无状态。

    https://developer.android.com/jetpack/compose/state#state-hoisting

    状态提升指的是,每当你创建任何子组合函数并且它被多次重用时,将它们变为无状态(Stateless)。在子组合函数中不应该包含任何remember{mutableState()},而在父组合中调用此子组合函数时,将其设为有状态(Stateful)。这样做可以方便地复用子组合函数。

    父组合函数 - 有状态(Stateful
    子组合函数 - 无状态(Stateless

    无状态提升

    @OptIn(ExperimentalMaterial3Api::class)
    @Composable
    fun WithoutStateHoisting() {
    
        var text by remember { mutableStateOf("") }
    
        TextField(value = text, onValueChange = { text = it })
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如上例所示,我们创建了一个组合函数,其中包含一个TextField并且在其中保存了一个状态。

    这个例子没有问题,但是假设我们想要重用这个WithoutStateHoisting()组合函数,那么我们很难做到这一点。

    如果我想创建一个带有用户名和电子邮件字段的登录页面,我们可以在父组合中调用此组合函数两次,但问题是如何管理状态,因为我们在子组合函数中定义了状态,那么我怎么能够管理或识别出两个状态(邮箱和用户名)呢?

    为了解决这个问题,我们需要依赖状态提升。

    使用状态提升

    @OptIn(ExperimentalMaterial3Api::class)
    @Composable
    fun WithStateHoistingExample(
        title: String,
        value: String,
        onValueChange: (String) -> Unit
    ) {
    
        TextField(value = value, onValueChange = onValueChange, placeholder = { Text(text = title) })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    现在你可以看到,在上面的代码中,我们从这里移除了状态,而是使用了onValueChange: (String) -> Unit来将值更新/发送到父组合函数。

    value:无论数据来自父组合还是子组合,都会在TextField中更新。

    而且好消息是,这个组合函数是可重用的。

    @Composable
    fun StateHoisting(
        modifier: Modifier
    ) {
    
        var username by remember { mutableStateOf("") }
        var email by remember { mutableStateOf("") }
    
        Column(
            modifier = modifier
                .padding(20.dp)
                .fillMaxSize(),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
    
            WithStateHoistingExample(
                title = stringResource(R.string.username),
                value = username,
                onValueChange = { username = it })
    
            Spacer(modifier = Modifier.height(20.dp))
    
            WithStateHoistingExample(
                title = stringResource(R.string.email),
                value = email,
                onValueChange = { email = it })
    
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    你可以看到我们在上面创建了两个状态,用户名和电子邮件,并将这些状态传递到子组合函数WithStateHoistingExample()中。

    结论

    状态提升是在Jetpack Compose中推荐使用的一种方式。请注意,如果你的子组合函数被多次重用,请不要使其有状态函数( stateful),始终使用状态提升以便可以重用并使它们感觉独立。

    Github

    https://github.com/nameisjayant/compose-blogs-repository/tree/main/app/src/main/java/com/nameisjayant/articlesrepository/ui/stateHositing?source=post_page

  • 相关阅读:
    PHP+MySQL制作简单动态网站(附详细注释+源码)
    查询效率提升10倍!3种优化方案,帮你解决MySQL深分页问题
    最优乘车——最短路
    电路美之运放
    paramiko 3
    ubuntu 23 使用教程
    【愚公系列】2022年10月 微信小程序-优购电商项目-⾃定义组件传参
    Spring - Spring Cloud Gateway网关实战及原理解析
    通过ISO9001认证,如何实现质量体系有效性
    3、后台数据库连接以及工具类编写 [木字楠博客]
  • 原文地址:https://blog.csdn.net/u011897062/article/details/133694556