重组究竟发生在什么时候?改变状态或改变输入

When recomposition happens exactly? with changing the state or also with changing the input

据我了解,与任何状态相关的每个代码部分都会随着状态的变化而改变(重组)→

并且每个状态都是可观察的,依赖的 UI 部分观察该状态并订阅它(状态),每当状态发生变化时,它都会收到通知(重绘 [=26= 的那部分]) 和正在发生的重组。

但是googleThinking in compose这篇文章里说重组是随着输入的变化而发生的,所以我很困惑。

Recomposition is the process of calling your composable functions again when inputs change. This happens when the function's inputs change. When Compose recomposes based on new inputs, it only calls the functions or lambdas that might have changed, and skips the rest. By skipping all functions or lambdas that don't have changed parameters, Compose can recompose efficiently.

此外,在其他 sample of compose-roadmap 中,鼓励提升状态以使可组合函数无状态以避免重组

所以,如果有人能说清楚重组只发生在状态变化或输入变化也会导致,那就太好了?

提前感谢您的帮助

当参数值更改或可组合函数中的可变状态变量更新时,就会发生重组。

无状态函数(有时称为“不可变”函数)是函数中不存储任何数据的函数。这意味着如果您重复调用该函数,它将与您第一次调用它时一样。该函数在每次调用时都不会保留任何变量的内存。

提升可组合项的状态意味着将状态变量保存在可组合项之外,并将这些状态变量的值作为普通参数传递到可组合项中。这允许您重用可组合项。如果您要创建一个要从一个项目重用到另一个项目的可组合项库,这一点尤其重要。库的用户可以放心,可组合项不需要任何状态依赖项。如果您想要一个真正无状态的可组合项,您将避免执行诸如传入视图模型之类的操作。视图模型非常依赖于它所在的应用程序,并且其中包含非常特定于该应用程序的代码。无状态可组合项不依赖于应用程序,因此可以在其他地方重复使用。

这并不意味着您不能在可组合项中使用视图模型。最初 Google 在 Compose 刚出来时反对这一点,但意识到这对开发人员来说非常尴尬。如果开发人员没有理由在出现的屏幕之外制作可重用的可组合项,则提升每个可组合项的状态会变得很痛苦,从而导致不必要的样板代码。所以一般规则是,如果您的可组合项不会在其他地方重复使用,并且您需要访问视图模型数据,您可以将视图模型作为参数传入,或者通过其他方式在可组合项中访问它。

除了视图模型之外,您可能仍然希望使可组合的有状态,即使它需要被重用。一个很好的例子是,如果您正在使用 TextField。当您输入文本时,您希望文本出现。如果不使用状态变量来保留键入的字符,您将看不到 TextField 更新。因此,使用局部状态变量来存储输入的字符是可以接受的。虽然这不会使可组合项成为无状态的,但它仍然是您需要实现的东西。但是,即使在此示例中,您仍然可以通过将键入的字符传回提升函数并将其存储在视图模型状态变量中来使其无状态,这反过来会触发提升函数重组可组合项并传入文本TextField 需要。但这是相当复杂的,并且只是为了让字符显示在 TextField 中而进行一次大的往返,因此不推荐。不过,如果您有一个非常复杂的 TextField 可组合项,并且您需要在键入字符时处理视图模型中的字符,那么您可能想要这样做——例如为 url 执行建议查找的情况。

因此,即使您的可组合项是无状态的,但您的视图模型具有提升函数正在观察的可变状态变量,如果该变量的可变状态发生变化,提升函数也会重新组合。但是,提升的可组合项正在调用的可组合项是否被重组取决于该可组合项的参数值是否发生变化。如果它们发生变化,就会发生重组。