rememberUpdatedState

Jetpack Compose Senior Kotlin 2.0+ API 24+ Reviewed By Best Latest Apps

Spot the bug

After 3 s, the effect calls an outdated callback if the parent passed a new one meanwhile. Which line uses the stale value?

  1. @Composable
  2. fun Splash(onTimeout: () -> Unit) {
  3. LaunchedEffect(Unit) {
  4. delay(3_000)
  5. onTimeout()
  6. }
  7. }
Hint 1 of 1

Which onTimeout does the coroutine see after a recomposition?

Choose an answer, then open Show answer below to check it.

Show answer
  • Answer: line 5 onTimeout()

The coroutine captured the first onTimeout. Use val current by rememberUpdatedState(onTimeout) and call current() here.

30-second answer

A long-running effect captures values when it starts. If a callback parameter changes later, the effect still calls the old one, unless you restart the effect, which may not be wanted, like a splash timeout. rememberUpdatedState(onTimeout) gives the effect a State that always holds the latest value without restarting it.

Practise saying it · 30 s. No recording, just a timer

Explain rememberUpdatedState.

Say your answer out loud, then check which of these points you covered:

  • Long effects capture old values
  • It holds the latest without restarting
  • Use keys when you want a restart

Deep dive

Pattern: val current by rememberUpdatedState(onTimeout), then LaunchedEffect(Unit) { delay(3_000); current() }.

Use it when the effect should not restart but must see the latest value.

If the effect should restart when the value changes, make the value a key instead.

Strong skipping remembers lambdas, but that doesn't help a coroutine that captured the old lambda.

Common mistakes

  • Adding the callback as a key and restarting the timer every recomposition.
  • Capturing a parameter in a long effect and calling a stale version.
  • Using it for values that should restart the effect.

Senior take & follow-ups

Explain the stale-capture bug clearly; that's the whole point.

Follow-up questions

Think of your answer first, then open the hint.

  1. Should a changing callback restart a 3-second timer?

    Show hint

    Usually not; that's when you use rememberUpdatedState.

  2. What's the alternative if restarting is fine?

    Show hint

    Use the value as a LaunchedEffect key.

Suggest a fix if something here is wrong or out of date.