谈谈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 })

}

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

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

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

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

使用状态提升

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun WithStateHoistingExample(
    title: String,
    value: String,
    onValueChange: (String) -> Unit
) {

    TextField(value = value, onValueChange = onValueChange, placeholder = { Text(text = title) })
}

现在你可以看到,在上面的代码中,我们从这里移除了状态,而是使用了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 })

    }

}

你可以看到我们在上面创建了两个状态,用户名和电子邮件,并将这些状态传递到子组合函数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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Calvin880828

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值