为什么在Jetpack Compose中需要使用SideEffect?
为什么在Compose主题里需要用SideEffect?
你现在删了SideEffect没看出变化,是因为当前场景的重组逻辑刚好让两种写法效果一致,但SideEffect是用来规范副作用执行时机和频率的,能避免潜在问题。
核心原因拆解:
Compose的重组逻辑是「只更新状态变化涉及的部分」,但直接在Composable函数里写systemUiController.setSystemBarsColor这种副作用代码,会有两个隐患:
- 无效重复执行:只要主题Composable因为任何原因重组(比如其他主题参数变化,但背景色没改),这段代码都会跑一遍,做无意义的重复操作。
- 时序风险:Compose重组是并行无序的,直接执行副作用可能在状态还没完全计算好时就触发,导致拿到的
backgroundColor不是最新值。
而SideEffect的作用就是给副作用加了两层保障:
- 只有当它依赖的状态(这里是
backgroundColor)发生变化时,才会执行; - 必须等到当前Composable重组完全完成后才执行,确保拿到的状态都是最新的。
能感受到差异的场景:
如果后续你给主题加了一个可切换的「文字强调色」,当用户切换这个颜色时,背景色没变,但主题Composable会重组。这时候:
- 不用SideEffect的写法:会重复调用
setSystemBarsColor,做无用功; - 用SideEffect的写法:因为
backgroundColor没变化,所以完全不会执行这段代码。
你的两种代码对比:
带SideEffect的写法:
@Composable fun Theme(...) { val systemUiController = rememberSystemUiController() val backgroundColor = MaterialTheme.colorScheme.background SideEffect { systemUiController.setSystemBarsColor(color = backgroundColor) } .... }
不带SideEffect的写法:
@Composable fun Theme(...) { val systemUiController = rememberSystemUiController() val backgroundColor = MaterialTheme.colorScheme.background systemUiController.setSystemBarsColor(color = backgroundColor) .... }
内容的提问来源于stack exchange,提问作者6155031
相关产品推荐
相关产品推荐

