rememberUpdatedState
@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:
LaunchedEffect
s 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)
}
}
// ...
}
}