SideEffect的使用:

5 阅读2分钟

一、先一句话记住

SideEffect = 专门用来在 Compose 中执行 “非界面副作用” 的函数

什么叫副作用

  • 发送 Analytics 埋点
  • 更新外部变量
  • 调用第三方 SDK 方法
  • 打印日志
  • 执行一次性操作
  • 不影响 UI、不返回 UI 状态的逻辑

规则:Compose 重组(Recomposition)时,SideEffect 一定会执行!

二、官方定义

kotlin

fun SideEffect(block: () -> Unit)
  • 每次重组成功后同步执行
  • 在 Composition 范围内执行
  • 不能挂起(不能写 suspend)
  • 没有 key,每次重组都跑

三、最核心特点 ✅

  1. 每次重组都会执行
  2. 同步执行(马上跑)
  3. 不能执行异步 / 协程
  4. 没有 key,不受控
  5. 专门用于非 UI 副作用

四、最标准使用示例

@Composable
fun MyComposable(name: String) {
    // 每次重组都会执行
    SideEffect {
        // 埋点
        Log.d("Compose", "组件重组了,name = $name")

        // 更新外部变量
        externalViewModel.updateName(name)
    }

    Text(text = name)
}

五、SideEffect 最常用场景

1. 日志 / 埋点(每次重组上报)

kotlin

SideEffect {
    Analytics.trackPage("HomePage")
}
2. 更新外部非 Compose 状态

kotlin

SideEffect {
    // 通知外部系统状态变化
    audioWaveView.setAmplitude(amplitude)
}
3. 执行一次性同步操作

kotlin

SideEffect {
    // 执行SDK同步方法
    NimSDK.updateStatus(status)
}
4. 避免在重组中直接执行副作用(非常重要)

❌ 错误:

kotlin

@Composable
fun Test() {
    // ❌ 直接写在这里会在重组时无限执行!
    Log.d("xxx", "重组") 
    Text("123")
}

✅ 正确:

kotlin

@Composable
fun Test() {
    SideEffect {
        Log.d("xxx", "重组") // ✅ 安全、受控
    }
    Text("123")
}

六、SideEffect 与 LaunchedEffect 区别(面试必考)

特性SideEffectLaunchedEffect
执行时机每次重组后同步key 变化时异步
是否可挂起❌ 不可以✅ 可以(suspend)
是否受控❌ 每次重组都跑✅ key 控制
用途同步副作用异步任务(网络、协程)
例子埋点、更新外部变量请求接口、播放动画

七、SideEffect 重要规则

  1. 不能在里面执行耗时操作
  2. 不能更新 Compose State(会导致死循环)
  3. 每次重组都会跑
  4. 必须是同步操作
  5. 专门用于和 UI 无关的逻辑

八、什么时候必须用 SideEffect?

  • 你要执行非 UI 操作
  • 这个操作必须在组件成功显示后执行
  • 这个操作每次重组都需要执行
  • 你不想它因为重组而被漏掉

九、最简单记忆口诀

重组完,同步跑,无协程,副作用。