Skip to content

State and remember

State and Remember Deep Dive

Overview

State is the central driver of Compose rendering. remember stores values across recompositions, while Compose snapshot state notifies the runtime when values change.

Core Concepts

  • mutableStateOf creates observable state.
  • remember preserves value while composable stays in composition.
  • rememberSaveable restores value after configuration/process recreation.
  • Keys control reset behavior for remembered values.

Runtime Internals

remember stores values in slot table positions. If call order and keys match, runtime reuses the stored value; otherwise, it drops and recreates it.

MutableState integrates with snapshots so writes can invalidate readers and schedule recomposition safely.

Composition / Recomposition Flow

  • Compose reads state.value during composition.
  • Runtime records that read for the current group.
  • State write invalidates dependent group(s).
  • Recomposition re-executes group and reuses remembered values when valid.

State Management

Use ownership levels deliberately:

  • local widget state: text field focus, expansion toggles
  • screen state: ViewModel StateFlow<UiState>
  • restorable UI state: rememberSaveable

Avoid storing mutable collections directly inside state without immutable wrappers.

Code Examples

@Composable
fun SearchBar() {
    var query by rememberSaveable { mutableStateOf("") }

    TextField(
        value = query,
        onValueChange = { query = it },
        label = { Text("Search") }
    )
}

@Composable
fun UserCard(userId: String) {
    // Recreate avatar painter if identity input changes.
    val avatarPainter = remember(userId) { loadAvatarPainter(userId) }
    Image(painter = avatarPainter, contentDescription = null)
}

Common Interview Questions

  • Q: Why does Compose prefer immutable UI models? A: Explain runtime behavior: what invalidates state, how recomposition is scoped, where side effects live, and how to verify frame stability with profiler traces.
  • Q: When does remember lose state? A: Explain runtime behavior: what invalidates state, how recomposition is scoped, where side effects live, and how to verify frame stability with profiler traces.
  • Q: How does rememberSaveable decide what can be saved? A: Explain runtime behavior: what invalidates state, how recomposition is scoped, where side effects live, and how to verify frame stability with profiler traces.
  • Q: What are key-related state bugs in dynamic lists? A: Answer from runtime mechanics: state ownership, recomposition triggers, effect lifecycle, and frame-time impact measured with tooling.

Production Considerations

  • Keep remembered state minimal and local.
  • Hoist state if multiple children need shared ownership.
  • Prefer stable IDs as keys.
  • Use custom Saver for non-primitive restorable objects.

Performance Insights

  • Overusing remember for cheap values can add complexity without gains.
  • Missing keys can retain stale expensive resources.
  • Correct state boundaries reduce invalidation blast radius.

Senior-Level Insights

At senior/staff interviews, explain both API and runtime model:

  • remember is slot-table backed positional storage
  • state writes are snapshot transactions
  • incorrect identity assumptions are a top source of flaky UI behavior