rememberUpdatedState

Composable Function

Common
@Composable
public fun <T> rememberUpdatedState(newValue: T): State<T>

remember a mutableStateOf newValue and update its value to newValue on each recomposition of the rememberUpdatedState call.

rememberUpdatedState should be used when parameters or values computed during composition are referenced by a long-lived lambda or object expression. Recomposition will update the resulting State without recreating the long-lived lambda or object, allowing that object to persist without cancelling and resubscribing, or relaunching a long-lived operation that may be expensive or prohibitive to recreate and restart. This may be common when working with DisposableEffect or LaunchedEffect, for example:

LaunchedEffects often describe state machines that should not be reset and restarted if a parameter or event callback changes, but they should have the current value available when needed. For example:

By using rememberUpdatedState a composable function can update these operations in progress.

Code Examples

rememberUpdatedStateSampleWithDisposableEffect

@Suppress("UnnecessaryLambdaCreation")
fun rememberUpdatedStateSampleWithDisposableEffect() {
    @Composable
    fun EventHandler(dispatcher: Dispatcher, onEvent: () -> Unit) {
        val currentOnEvent by rememberUpdatedState(onEvent)
        // Event handlers are ordered and a new onEvent should not cause us to re-register,
        // losing our position in the dispatcher.
        DisposableEffect(dispatcher) {
            val disposable =
                dispatcher.addListener {
                    // currentOnEvent will always refer to the latest onEvent function that
                    // the EventHandler was recomposed with
                    currentOnEvent()
                }
            onDispose { disposable.dispose() }
        }
    }
}

rememberUpdatedStateSampleWithLaunchedEffect

fun rememberUpdatedStateSampleWithLaunchedEffect() {
    @Composable
    fun NotificationHost(state: NotificationState, onTimeout: (Notification) -> Unit) {
        val currentOnTimeout by rememberUpdatedState(onTimeout)
        state.currentNotification?.let { currentNotification ->
            LaunchedEffect(currentNotification) {
                // We should not restart this delay if onTimeout changes, but we want to call
                // the onTimeout we were last recomposed with when it completes.
                delay(NotificationTimeout)
                currentOnTimeout(currentNotification)
            }
        }
        // ...
    }
}