原文地址: 是否应该将Compose中的状况拆分

前言

Compose中单个页面是否应该运用单个状况进行办理?

为什么会有以上这种疑问呢?莫非不应该就是这样的吗?
其实不然,咱们知道Compose是经过重组来刷新UI的,当一个State产生改动时,其对应的可重组函数的Lambda会重新执行,为了方便,咱们一般会会直接运用一个完好的State来办理一个界面的显示。
所以咱们在更新State时,而这个State的可重组范围是整个界面的Compose函数,基本会让整个界面都产生重组而不会越过任何可重组项。
下面是一个简单的比如:

// 一个整合的State
data class XModelState(
    val name: String,
    val age: Int,
    val intro: String
    ...
)
Column(
    modifier = Modifier
    .fillMaxSize()
    .padding(16.dp)
) {
    println("Column")
    Wrapper {
        Text(text = "Name is ${modelState.name}").also {
            println("Name changed")
        }
    }
    Wrapper {
        Text(text = "Age is ${modelState.age}").also {
            println("Age changed")
        }
    }
    Wrapper {
        Text(text = "Intro is ${modelState.intro}").also {
            println("Intro changed")
        }
    }
    Button(
        modifier = Modifier.fillMaxWidth(),
        onClick = {
            modelState = modelState.copy(
                name = "Dougie ${Random.nextInt(0, 10)}",
                age = age + 1
            )
        }
    ) {
        Text(text = "Update Model")
    }
}

以上代码中,当点击Update Model按钮来修改modelState时,3个Wrapper全部都产生重组。

*       ----------------     -----------------      ---------------------
*       | Click Button |  -> | State changed |  ->  | trigger recompose |
*       ----------------     -----------------      ---------------------

但假定界面内容比较复杂,而这个State也很大许多特点,在更新其间某个或某些特点时,产生重组时,重组了整个可重组项,这不是咱们想要的结果。咱们想要的是,在某个或某些特点产生更新时,只重组运用到该特点的可重组项,而其他的则越过(skip re-compose).

为了防止这个情况,目前Compose也没供给相关的api,如同也只能经过切割状况了,对应文章的标题。

拆分方式

1. ViewModel层保存多个揭露的State

在ViewModel combine的时分就将State切割并供给多个State叫个UI层运用,而在操作的时分,咱们也只会改动其对应的小State,其他State不会改变,
所以Compose上也只会重组其对应的可重组Lambda,而其他的则会越过重组。

2. 运用 derivedStateOf

在View层,依然是拿到整个大的State,咱们经过添加内部特点并使derivedStateOf这个办法将State切割。

val age by remember {
    derivedStateOf {
        modelState.age
    }
}
val intro by remember {
    derivedStateOf {
        modelState.intro
    }
}

如上,将age和intro切割出来,在点击按钮是,age+1,而intro不变,经过日志,发现只有Age Changed,所以intro的被越过重组了。

Note: 在日常开发中,需求feature会越来越多,State也会随之而添加,以上两种方式尽管一定程度上能削减重组,可是也很大程度上添加了维护作业和带来新的问题。

总结

在Compose上,UI的更新必定脱离不了重组,所以重组本身并不是大问题,咱们需要留意的是尽量在可重组项中尽量少操作剩余的作业。所以一般咱们不必在意这些,因为Compose帮我做了许多优化的作业了。
当然如果在某个UI上,有其间一部份UI改变相对比较频繁,而其他则很少,此刻我主张对状况进行拆分