【问题标题】:SideEffects in Jetpack ComposeJetpack Compose 中的副作用
【发布时间】:2021-11-12 22:16:00
【问题描述】:

我知道除了composablecomposition的行为之外,其他所有行为都是副作用。那么,在TextField 的情况下,更改onValueChange 中的TextFieldValue 会产生副作用吗?还有,在composable中显示toast消息会不会有副作用?

【问题讨论】:

    标签: android android-jetpack-compose side-effects


    【解决方案1】:

    让我们先了解几个函数式编程术语

    Idempotent - 表示调用相同的函数 n 次,提供相同的输入,应该会产生相同的输出。

    您的函数需要在 compose 世界中为 idempotent,才能使重组工作 - 作为 compose 运行时,在初始组合期间 memoizes,并且如果在重组期间函数的输入没有改变(或者说树节点未更新),撰写运行时将使用相同的memoized 结果。函数不是idempotent 将导致重组期间出现意外行为。

    Purefunction - 不包含副作用的函数。

    Side-effect - 这是任何超出函数范围的操作,以做一些意想不到的事情。

    In compose world - side-effect could be a change to the state of the app that happens outside of the scope of the function, things like setting a global variable, updating cache, making a network query, reading from file etc.. 
    
    It makes the function non-deterministic and can lead to race condition and unexpected behavior. 
    
    To generalize, side-effects are unexpected actions happening on the side, out of what callers would expect from the function, and that alter its behavior.
    

    正如我们所说的那样,函数应该没有副作用,但是在少数情况下,我们需要从可组合运行副作用,以处理这些情况,组合运行时提供不同的effect-handlers,这将确保,它们根据 compose 生命周期在正确的时间运行。

    因此,在 TextField 的情况下,正在更改 TextFieldValue onValueChange 有副作用吗?

    在我看来,它更像是 unidirectional 数据流,并且由于状态是在可组合(可组合的内部存储器)范围内管理的,所以它不是副作用。

    另外,以可组合的形式显示 toast 消息是否有副作用?

    这可能是一个副作用,如果没有正确处理效果,考虑到你最终不会在重新组合时调用 toast。

    【讨论】:

      【解决方案2】:

      根据 Jetpack Compose 中 SideEffect 的定义,副作用是发生在可组合函数范围之外的应用程序状态更改。 在 TextField 中,我们无法更改我们交换值的文本字段的状态。 您可以在 CoreTextField Compose 函数中看到它:

                  if (value != it) {
                      onValueChange(it)
                  }
              }, 
      

      所以在 onValueChange 中,没有使用 SideEffects。

      同样在 Toast 消息的情况下,但 Toast 不是用 Compose 编写的,因此它不是一个 compose 函数,我们可以从 compose 函数外部调用它,因此没有副作用使用。

      【讨论】:

        猜你喜欢
        • 2022-07-29
        • 2021-03-05
        • 2022-10-19
        • 2021-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多