AFAIK这里没有区别。这只是一个巧合,两个结构在这里做同样的事情,在这个上下文中。但是,有区别! 最大的一个问题是derivedStateOf是不可组合的,它自己没有缓存(remember有)。所以derivedStateOf意味着只有在密钥更改时才必须运行的长时间计算。或者,它可以用来合并多个不可组合的状态(例如,在自定义类中)。 我认为确切的解释是模糊的“局外人”,我们需要一些输入从一些组成团队成员在这里:)。我上面的源代码是this one thread on slack和我自己的实验 编辑: 今天我学习了derivedStateOf的另一个用法,非常重要的一个。当使用一些非常常用的值进行计算时,它可以用于限制重组计数。 示例:
// we have a variable scrollState: Int that gets updated every time user scrolls
// we want to update our counter for every 100 pixels scrolled.
// To avoid recomposition every single pixel change we are using derivedStateOf
val counter = remember {
derivedStateOf {
(scrollState / 100).roundToInt()
}
}
// this will be recomposed only on counter change, so it will "ignore" scrollState in 99% of cases
Text(counter.toString()).
val result = remember(key1, key2) { computeIt(key1, key2) }在key1或key2发生变化时重新计算,但derivedStateOf用于跟踪一个或多个State/MutableState的变化,如文档中所述
var a by remember { mutableStateOf(0) }
var b by remember { mutableStateOf(0) }
val sum = remember { derivedStateOf { a + b } }
// Changing either a or b will cause CountDisplay to recompose but not trigger Example
// to recompose.
CountDisplay(sum)
var numberOfItems by remember {
mutableStateOf(0)
}
// Use derivedStateOf when a certain state is calculated or derived from other state objects.
// Using this function guarantees that the calculation will only occur whenever one
// of the states used in the calculation changes.
val derivedStateMax by remember {
derivedStateOf {
numberOfItems > 5
}
}
Column(modifier = Modifier.padding(horizontal = 8.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(text = "Amount to buy: $numberOfItems", modifier = Modifier.weight(1f))
IconButton(onClick = { numberOfItems++ }) {
Icon(imageVector = Icons.Default.Add, contentDescription = "add")
}
Spacer(modifier = Modifier.width(4.dp))
IconButton(onClick = { if (derivedStateMin) numberOfItems-- }) {
Icon(imageVector = Icons.Default.Remove, contentDescription = "remove")
}
}
if (derivedStateMax) {
Text("You cannot buy more than 5 items", color = Color(0xffE53935))
}
}
3条答案
按热度按时间pbossiut1#
derivedStateOf {}
用于当您的状态或密钥更改的次数超过您想要更新UI的次数时。它就像一个缓冲器,缓冲掉你不需要的更改。这是键控remember {}
和derivedStateOf {}
之间的主要区别。使用remember {}
,你仍然可以根据你的密钥变化进行重新组合,如果这是你需要的,这不是一件坏事。如果您不需要这些重组,那么derivedStateOf {}
就派上用场了。例如,仅当用户滚动
LazyColumn
时才显示按钮。firstVisibleItemIndex
将改变0、1、2等。因为用户滚动并导致每次改变时的重新组合。我只关心它是否为0,并且只想在条件改变时重新组合。
derivedStateOf
是我的缓冲区,它缓冲了所有我不需要的额外状态更改,并将重组限制在只有derivedStateOf
更改时。对于问题中给出的示例,正确的API是
remember(key1, key2) {}
,而不是derivedStateOf {}
,因为您希望UI在密钥更改时随时更新,而没有任何更改需要缓冲。更新:在https://www.youtube.com/watch?v=ahXLwg2JYpc&t=948s演讲中有
derivedStateOf
的详细解释kx5bkwkv2#
AFAIK这里没有区别。这只是一个巧合,两个结构在这里做同样的事情,在这个上下文中。但是,有区别!
最大的一个问题是
derivedStateOf
是不可组合的,它自己没有缓存(remember
有)。所以derivedStateOf
意味着只有在密钥更改时才必须运行的长时间计算。或者,它可以用来合并多个不可组合的状态(例如,在自定义类中)。我认为确切的解释是模糊的“局外人”,我们需要一些输入从一些组成团队成员在这里:)。我上面的源代码是this one thread on slack和我自己的实验
编辑:
今天我学习了
derivedStateOf
的另一个用法,非常重要的一个。当使用一些非常常用的值进行计算时,它可以用于限制重组计数。示例:
我的来源是直接的,因为它可以-从撰写运行时和快照系统的作者,查克Jazdzewski自己。我强烈建议在这里与他一起观看流:https://www.youtube.com/watch?v=waJ_dklg6fU
编辑2:
我们终于有了一些官方的性能文档,其中很少提到
derivedStateOf
。因此,derivedStateOf
的官方目的是限制组合计数(如我的示例中所示)。酱料n3h0vuf23#
val result = remember(key1, key2) { computeIt(key1, key2) }
在key1
或key2
发生变化时重新计算,但derivedStateOf
用于跟踪一个或多个State/MutableState的变化,如文档中所述当需要跟踪State对象的属性更改时,使用derivedStateOf很方便。存储在State中的值可以是一个对象,但是当你需要跟踪对象的一个或一些属性时,你需要使用derivedStateOf。如果它不是从一个
State/MutableState
或带有@Stable
注解的接口的对象派生的,Composable将不会重组,因为重组需要状态更改。例如,在某个阈值或状态之后触发另一次重组所需的输入布局或项目数量。
这是WhatsApp的文本输入,通过从文本中阅读,根据文本是否为空来显示图标