Android Compose 副作用

use*_*179 5 android android-jetpack-compose

这2个有什么区别?一个使用 SideEffect,另一个则不使用。“每次成功重组时都会调用 SideEffect”,但如果没有 SideEffect,它也会在每次重组时运行。

@Composable
fun BackHandler(
    backDispatcher: OnBackPressedDispatcher,
    enabled: Boolean = true, // Whether back events should be intercepted or not
    onBack: () -> Unit
) {
    val backCallback = remember { /* ... */ }

    // On every successful composition, update the callback with the `enabled` value
    // to tell `backCallback` whether back events should be intercepted or not
    SideEffect {
        backCallback.isEnabled = enabled
    }

    /* Rest of the code */
}

@Composable
fun BackHandler(
    backDispatcher: OnBackPressedDispatcher,
    enabled: Boolean = true, // Whether back events should be intercepted or not
    onBack: () -> Unit
) {
    val backCallback = remember { /* ... */ }

    backCallback.isEnabled = enabled

    /* Rest of the code */
}
Run Code Online (Sandbox Code Playgroud)

chu*_*ckj 6

区别在于“成功”一词。即使调用了,也不能保证调用的效果 BackHandler是结果组合的一部分(可以丢弃它的方法很少且难以描述)。SideEffect确保 lambda 仅在满足条件时才被执行。

ASideEffect确保,

  1. 仅当封闭范围的效果实际上是结果合成的一部分时才应用它。
  2. 在将组合实现为结果组合(即已LayoutNode创建并成功插入到布局树中)后调用它。这在内部很重要(对于焦点等事情),但在框架内部之外可能没有那么多应用。
  3. 它是一个单独的快照,与合成时拍摄的快照不同,任何可观察到的更改都会影响下一个合成,而不是本次合成。
  4. 它总是在应用程序的线程(即LayoutNodes 的主线程)上调用。

只有上面的 (1) 与这里相关。

可组合函数具有未被封装的副作用SideEffect或类似构造被认为是不好的做法,因为这样做打破了可组合函数相对于组合是引用透明的假设。