compose Effect概念

这个问题问得非常到位 ,而且现在正是你该把这件事**"一次性讲清楚"的时候了 👍
你已经学了 State、重组、生命周期、SideEffect / LaunchedEffect / DisposableEffect,如果
不把「Effect 是什么」抽象成一个统一概念**,后面一定会越学越乱。

我给你一个工程级、可在脑子里复用的定义


一、先给你一句话定义(核心)

Compose 中的 Effect(副作用)=
在 UI 声明(Composable 函数)之外,对"外部世界"产生影响的操作。

关键词:

  • 不只是返回 UI
  • 会改变 UI 之外的状态
  • 不能被安全地重复执行

二、为什么 Compose 一定要"显式 Effect"?(本质原因)

因为 Compose 的核心模型是:

kotlin 复制代码
UI = f(State)

而 Composable 函数有三个特点:

  1. 会被反复执行(重组)
  2. 执行顺序不稳定
  3. 执行结果可能被丢弃

👉 所以:

任何"有副作用的代码",都不能直接写在 Composable 函数体里


三、什么算"副作用"?(你可以直接用这个判断)

属于 Effect 的事情:

  • 启动协程
  • 请求网络
  • 订阅 Flow
  • 打日志(某些情况)
  • 修改系统 UI(状态栏、亮度)
  • 注册监听 / Receiver
  • 读写文件
  • 调用 ViewModel 的业务方法(有条件)

不属于 Effect 的事情:

  • if / when
  • UI 计算
  • 纯数据转换
  • derivedStateOf

四、Compose 是怎么"管副作用"的?

Compose 提供了一整套 Effect API,统一规则是:

Effect 只在"成功的重组"之后执行,并且与重组生命周期绑定


五、Effect 家族一览(你已经见过,但现在要统一理解)

Effect API 解决的问题
LaunchedEffect 启动协程副作用
DisposableEffect 有生命周期的副作用
SideEffect 同步副作用
produceState 异步 → State
rememberUpdatedState 解决闭包过期
snapshotFlow State → Flow

👉 它们不是零散 API,而是一个体系。


六、Effect 的"统一执行模型"(非常重要)

所有 Effect 都遵守这条规则:

text 复制代码
Composable 执行(可能多次)
   ↓
如果本次重组被提交
   ↓
Effect 执行

👉 Effect 永远不会在"半途"执行


七、用一句"工程级心智模型"记住 Effect

Composable 描述 UI,
Effect 让 UI 影响世界。


八、结合 MVI 的真实定位(你关心的)

MVI + Compose 中:

  • Intent → 改变 State(VM)
  • State → 驱动 UI(Composable)
  • Effect → 连接 UI 与外部系统

示例(标准写法)

kotlin 复制代码
@Composable
fun HomeScreen(vm: HomeViewModel) {
    val uiState by vm.uiState.collectAsState()

    LaunchedEffect(Unit) {
        vm.sendIntent(Intent.Load)
    }

    if (uiState.error != null) {
        SideEffect {
            showToast(uiState.error)
        }
    }
}

九、一个非常重要的误区(一定要避开)

❌ 错误理解

"Effect 就是生命周期回调"

✅ 正确理解

Effect 是"声明式生命周期"下的副作用管理工具


十、你现在已经形成一个「完整闭环」了

你已经掌握了:

  • State → UI
  • State → Recomposition
  • Recomposition → Effect
  • Effect → 外部世界

👉 这就是 Compose 的完整运行模型


最后送你一句话(建议你记住)

如果一段代码:
离开这个 Composable 还能存在,
那它就必须写在 Effect 里。


相关推荐
stevenzqzq3 天前
Compose 中最常用的布局** —— Box / Row / Column / ConstraintLayout教程
compose
stevenzqzq3 天前
LaunchedEffect的作用和如何使用
compose
MengFly_4 天前
Compose案例 — Android 调用系统相机拍照
android·kotlin·compose
氦客4 天前
Android Compose : 传统View在Compose组件中的等价物
android·compose·jetpack·对比·传统view·等价物·compose组件
氦客5 天前
UI编程的发展史 : 结合命令式UI和声明式UI
android·compose·声明式ui·ui编程·命令式ui·ui编程发展史·标记语言
stevenzqzq7 天前
Compose Navigation 时序图
compose
stevenzqzq7 天前
Compose 状态 / 协程 总图
compose
儿歌八万首10 天前
Jetpack Compose 动画实战:让你的 UI 动起来
android·kotlin·动画·compose
儿歌八万首12 天前
Jetpack Compose 自定义布局解析
kotlin·compose·自定义布局
zFox12 天前
二、Kotlin高级特性以及Compose状态驱动UI
ui·kotlin·compose