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 里。


相关推荐
le1616166 天前
Android Compose——尺寸修饰符的调用顺序构成的不同尺寸约束效果
android·compose·modifier
le1616167 天前
Android Compose Modifier修饰符
android·compose·modifier
小书房7 天前
Android UI为什么由XML转向Compose
xml·ui·compose·声明式ui
le1616168 天前
Android Compose基础布局——从传统XML的视角切入了解
xml·compose
赏金术士13 天前
企业级 Jetpack Compose 项目(入门版)最佳结构
android·kotlin·compose
Jomurphys14 天前
Compose 调用 - 液态玻璃 Backdrop
android·compose
氦客17 天前
Android Compose 图层的合成 : BlendMode
android·compose·jetpack·layer·blendmode·graphics·图层的合成
赏金术士18 天前
第六章:UI组件与Material3主题
android·ui·kotlin·compose
赏金术士18 天前
Jetpack Compose 底部导航实战教程(完整版)
android·kotlin·compose
程序员煊子19 天前
用 Cursor 从零搭一个 Compose 本地记账 App:实战记录与源码解析
android·kotlin·compose·cursor