Jetpack Compose中remember的底层原理及与MutableState的适配问题
Great question—let’s unpack each part of this to get a clear picture of how remember fits into Jetpack Compose’s state system.
How does remember work under the hood?
Jetpack Compose relies on a recomposition system: whenever state used in a composable changes, Compose re-runs the composable (and its relevant children) to update the UI. But by default, every time a composable recomposes, all variables inside it get reinitialized—unless you use remember.
Here’s the core breakdown of remember’s mechanics:
- It stores the value returned by its lambda in Compose’s Composition memory—a dedicated space tied to the composable’s position in the UI tree.
- When the composable recomposes,
rememberchecks if a value already exists for this specific "slot" in the Composition. If it does, it returns the existing value instead of re-running the lambda. - The "slot" is determined by the position of the
remembercall in your code (you can also pass custom keys torememberto override this behavior if needed).
In your counter code, remember { mutableStateOf(0) } ensures the same MutableState instance is retained across recompositions, so your counter value never resets randomly when the UI updates.
Why can’t we use var count = remember { 0 } or mutableStateOf(0) without remember?
Let’s break these two scenarios down individually:
var count = remember { 0 }rememberhere returns a plainIntvalue, not an observable state. When you try to incrementcount(likecount += 1), you’re just modifying a local variable—but Compose has no way to track this change. Since there’s no observable state update, Compose won’t trigger a recomposition, so the UI will never show the updated count.
mutableStateOf(0)withoutremembermutableStateOf(0)creates an observableMutableStateinstance, but withoutremember, every time the composable recomposes, a brand newMutableStateis created with the initial value0. So when you click the button, you increment the value of a temporary instance that gets discarded on the next recomposition—you’ll always see "I've been clicked 1 times" no matter how many times you tap.
Does remember only work with MutableState?
Absolutely not! remember can retain any type of value across recompositions—plain primitives, data classes, lists, custom objects, even functions. For example:
remember { "Hello, Compose" }(stores a String)remember { mutableListOf("Android", "iOS") }(stores a mutable list)remember { User(name = "Jane", age = 30) }(stores a custom data class)
The catch is: if you retain a non-observable value (like a plain List or data class), modifying its internal state won’t trigger recomposition. For example, if you have val list = remember { mutableListOf<String>() } and add an item to it, Compose won’t automatically update the UI. In those cases, you’d need to use observable collections (like mutableStateListOf) or manually trigger recomposition—but remember itself doesn’t care what type of value it’s holding.
内容的提问来源于stack exchange,提问作者Thracian

