{% setvar book_path %}/reference/androidx/_book.yaml{% endsetvar %} {% include "_shared/_reference-head-tags.html" %}

SnapshotStateKt

public final class SnapshotStateKt


Summary

Public methods

static final @NonNull State<@NonNull T>

Collects values from this StateFlow and represents its latest value via State.

static final @NonNull State<@NonNull R>
@Composable
<T extends R, R extends Object> collectAsState(
    @NonNull <Error class: unknown class><@NonNull T> receiver,
    @NonNull R initial,
    @NonNull CoroutineContext context
)

Collects values from this Flow and represents its latest value via State.

static final @NonNull State<@NonNull T>
@StateFactoryMarker
<T extends Object> derivedStateOf(@NonNull Function0<@NonNull T> calculation)

Creates a State object whose State.value is the result of calculation.

static final @NonNull State<@NonNull T>
@StateFactoryMarker
<T extends Object> derivedStateOf(
    @NonNull SnapshotMutationPolicy<@NonNull T> policy,
    @NonNull Function0<@NonNull T> calculation
)

Creates a State object whose State.value is the result of calculation.

static final @NonNull T
<T extends Object> getValue(
    @NonNull State<@NonNull T> receiver,
    Object thisObj,
    @NonNull KProperty<@NonNull ?> property
)

Permits property delegation of vals using by for State.

static final @NonNull SnapshotStateList<@NonNull T>

Create a instance of MutableList that is observable and can be snapshot.

static final @NonNull SnapshotStateList<@NonNull T>

Create an instance of MutableList that is observable and can be snapshot.

static final @NonNull SnapshotStateMap<@NonNull K, @NonNull V>
@StateFactoryMarker
<K extends Object, V extends Object> mutableStateMapOf()

Create a instance of MutableMap that is observable and can be snapshot.

static final @NonNull SnapshotStateMap<@NonNull K, @NonNull V>
@StateFactoryMarker
<K extends Object, V extends Object> mutableStateMapOf(
    @NonNull Pair<@NonNull K, @NonNull V> pairs
)

Create a instance of MutableMap that is observable and can be snapshot.

static final @NonNull MutableState<@NonNull T>
@StateFactoryMarker
<T extends Object> mutableStateOf(
    @NonNull T value,
    @NonNull SnapshotMutationPolicy<@NonNull T> policy
)

Return a new MutableState initialized with the passed in value

static final @NonNull SnapshotMutationPolicy<@NonNull T>
<T extends Object> neverEqualPolicy()

A policy never treat values of a MutableState as equivalent.

static final @NonNull State<@NonNull T>
@Composable
<T extends Object> produceState(
    @NonNull T initialValue,
    @ExtensionFunctionType @NonNull SuspendFunction1<@NonNull ProduceStateScope<@NonNull T>, Unit> producer
)

Return an observable snapshot State that produces values over time without a defined data source.

static final @NonNull State<@NonNull T>
@Composable
<T extends Object> produceState(
    @NonNull T initialValue,
    Object key1,
    @ExtensionFunctionType @NonNull SuspendFunction1<@NonNull ProduceStateScope<@NonNull T>, Unit> producer
)

Return an observable snapshot State that produces values over time from key1.

static final @NonNull State<@NonNull T>
@Composable
<T extends Object> produceState(
    @NonNull T initialValue,
    Object keys,
    @ExtensionFunctionType @NonNull SuspendFunction1<@NonNull ProduceStateScope<@NonNull T>, Unit> producer
)

Return an observable snapshot State that produces values over time from keys.

static final @NonNull State<@NonNull T>
@Composable
<T extends Object> produceState(
    @NonNull T initialValue,
    Object key1,
    Object key2,
    @ExtensionFunctionType @NonNull SuspendFunction1<@NonNull ProduceStateScope<@NonNull T>, Unit> producer
)

Return an observable snapshot State that produces values over time from key1 and key2.

static final @NonNull State<@NonNull T>
@Composable
<T extends Object> produceState(
    @NonNull T initialValue,
    Object key1,
    Object key2,
    Object key3,
    @ExtensionFunctionType @NonNull SuspendFunction1<@NonNull ProduceStateScope<@NonNull T>, Unit> producer
)

Return an observable snapshot State that produces values over time from key1, key2 and key3.

static final @NonNull SnapshotMutationPolicy<@NonNull T>

A policy to treat values of a MutableState as equivalent if they are referentially (===) equal.

static final @NonNull State<@NonNull T>
@Composable
<T extends Object> rememberUpdatedState(@NonNull T newValue)

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

static final void
<T extends Object> setValue(
    @NonNull MutableState<@NonNull T> receiver,
    Object thisObj,
    @NonNull KProperty<@NonNull ?> property,
    @NonNull T value
)

Permits property delegation of vars using by for MutableState.

static final @NonNull <Error class: unknown class><@NonNull T>
<T extends Object> snapshotFlow(@NonNull Function0<@NonNull T> block)

Create a Flow from observable Snapshot state.

static final @NonNull SnapshotMutationPolicy<@NonNull T>

A policy to treat values of a MutableState as equivalent if they are structurally (==) equal.

static final @NonNull SnapshotStateList<@NonNull T>
<T extends Object> toMutableStateList(@NonNull Collection<@NonNull T> receiver)

Create an instance of MutableList from a collection that is observable and can be snapshot.

static final @NonNull SnapshotStateMap<@NonNull K, @NonNull V>
<K extends Object, V extends Object> toMutableStateMap(
    @NonNull Iterable<@NonNull Pair<@NonNull K, @NonNull V>> receiver
)

Create an instance of MutableMap from a collection of pairs that is observable and can be snapshot.

Public methods

collectAsState

@Composable
public static final @NonNull State<@NonNull T> <T extends Object> collectAsState(
    @NonNull <Error class: unknown class><@NonNull T> receiver,
    @NonNull CoroutineContext context
)

Collects values from this StateFlow and represents its latest value via State. The StateFlow.value is used as an initial value. Every time there would be new value posted into the StateFlow the returned State will be updated causing recomposition of every State.value usage.

import androidx.compose.material.Text
import androidx.compose.runtime.collectAsState

val value: String by stateFlow.collectAsState()
Text("Value is $value")
Parameters
@NonNull CoroutineContext context

CoroutineContext to use for collecting.

collectAsState

@Composable
public static final @NonNull State<@NonNull R> <T extends R, R extends Object> collectAsState(
    @NonNull <Error class: unknown class><@NonNull T> receiver,
    @NonNull R initial,
    @NonNull CoroutineContext context
)

Collects values from this Flow and represents its latest value via State. Every time there would be new value posted into the Flow the returned State will be updated causing recomposition of every State.value usage.

import androidx.compose.material.Text
import androidx.compose.runtime.collectAsState

val value: String by flow.collectAsState("initial")
Text("Value is $value")
Parameters
@NonNull CoroutineContext context

CoroutineContext to use for collecting.

derivedStateOf

@StateFactoryMarker
public static final @NonNull State<@NonNull T> <T extends Object> derivedStateOf(@NonNull Function0<@NonNull T> calculation)

Creates a State object whose State.value is the result of calculation. The result of calculation will be cached in such a way that calling State.value repeatedly will not cause calculation to be executed multiple times, but reading State.value will cause all State objects that got read during the calculation to be read in the current Snapshot, meaning that this will correctly subscribe to the derived state objects if the value is being read in an observed context such as a Composable function. Derived states without mutation policy trigger updates on each dependency change. To avoid invalidation on update, provide suitable SnapshotMutationPolicy through derivedStateOf overload.

import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable fun CountDisplay(count: State<Int>) {
    Text("Count: ${count.value}")
}

@Composable fun Example() {
    var a by remember { mutableStateOf(0) }
    var b by remember { mutableStateOf(0) }
    val sum = remember { derivedStateOf { a + b } }
    // Changing either a or b will cause CountDisplay to recompose but not trigger Example
    // to recompose.
    CountDisplay(sum)
}
Parameters
@NonNull Function0<@NonNull T> calculation

the calculation to create the value this state object represents.

derivedStateOf

@StateFactoryMarker
public static final @NonNull State<@NonNull T> <T extends Object> derivedStateOf(
    @NonNull SnapshotMutationPolicy<@NonNull T> policy,
    @NonNull Function0<@NonNull T> calculation
)

Creates a State object whose State.value is the result of calculation. The result of calculation will be cached in such a way that calling State.value repeatedly will not cause calculation to be executed multiple times, but reading State.value will cause all State objects that got read during the calculation to be read in the current Snapshot, meaning that this will correctly subscribe to the derived state objects if the value is being read in an observed context such as a Composable function.

import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable fun CountDisplay(count: State<Int>) {
    Text("Count: ${count.value}")
}

@Composable fun Example() {
    var a by remember { mutableStateOf(0) }
    var b by remember { mutableStateOf(0) }
    val sum = remember { derivedStateOf { a + b } }
    // Changing either a or b will cause CountDisplay to recompose but not trigger Example
    // to recompose.
    CountDisplay(sum)
}
Parameters
@NonNull SnapshotMutationPolicy<@NonNull T> policy

mutation policy to control when changes to the calculation result trigger update.

@NonNull Function0<@NonNull T> calculation

the calculation to create the value this state object represents.

getValue

public static final @NonNull T <T extends Object> getValue(
    @NonNull State<@NonNull T> receiver,
    Object thisObj,
    @NonNull KProperty<@NonNull ?> property
)

Permits property delegation of vals using by for State.

import androidx.compose.foundation.layout.Row
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State

// Composable function that manages a subscription to a data source, returning it as State
@Composable
fun observeSampleData(): State<String> = TODO()

// Subscription is managed here, but currentValue is not read yet
val currentValue by observeSampleData()

Row {
    // This scope will recompose when currentValue changes
    Text("Data: $currentValue")
}

mutableStateListOf

@StateFactoryMarker
public static final @NonNull SnapshotStateList<@NonNull T> <T extends Object> mutableStateListOf()

Create a instance of MutableList that is observable and can be snapshot.

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun Names() {
    var name by remember { mutableStateOf("user") }
    val names = remember { mutableStateListOf<String>() }

    Column {
        Row {
            BasicTextField(
                value = name,
                onValueChange = { name = it }
            )
            Button(onClick = { names.add(name) }) {
                Text("Add")
            }
        }
        Text("Added names:")
        Column {
            for (addedName in names) {
                Text(addedName)
            }
        }
    }
}

mutableStateListOf

@StateFactoryMarker
public static final @NonNull SnapshotStateList<@NonNull T> <T extends Object> mutableStateListOf(@NonNull T elements)

Create an instance of MutableList that is observable and can be snapshot.

mutableStateMapOf

@StateFactoryMarker
public static final @NonNull SnapshotStateMap<@NonNull K, @NonNull V> <K extends Object, V extends Object> mutableStateMapOf()

Create a instance of MutableMap that is observable and can be snapshot.

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun NamesAndAges() {
    var name by remember { mutableStateOf("name") }
    var saying by remember { mutableStateOf("saying") }
    val sayings = remember {
        mutableStateMapOf(
            "Caesar" to "Et tu, Brute?",
            "Hamlet" to "To be or not to be",
            "Richard III" to "My kingdom for a horse"
        )
    }

    Column {
        Row {
            BasicTextField(
                value = name,
                onValueChange = { name = it }
            )
            BasicTextField(
                value = saying,
                onValueChange = { saying = it }
            )
            Button(onClick = { sayings[name] = saying }) {
                Text("Add")
            }
            Button(onClick = { sayings.remove(name) }) {
                Text("Remove")
            }
        }
        Text("Sayings:")
        Column {
            for (entry in sayings) {
                Text("${entry.key} says '${entry.value}'")
            }
        }
    }
}

mutableStateMapOf

@StateFactoryMarker
public static final @NonNull SnapshotStateMap<@NonNull K, @NonNull V> <K extends Object, V extends Object> mutableStateMapOf(
    @NonNull Pair<@NonNull K, @NonNull V> pairs
)

Create a instance of MutableMap that is observable and can be snapshot.

mutableStateOf

@StateFactoryMarker
public static final @NonNull MutableState<@NonNull T> <T extends Object> mutableStateOf(
    @NonNull T value,
    @NonNull SnapshotMutationPolicy<@NonNull T> policy
)

Return a new MutableState initialized with the passed in value

The MutableState class is a single value holder whose reads and writes are observed by Compose. Additionally, writes to it are transacted as part of the Snapshot system.

import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val count = remember { mutableStateOf(0) }

Text(text = "You clicked ${count.value} times")
Button(onClick = { count.value++ }) {
    Text("Click me")
}
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val (count, setCount) = remember { mutableStateOf(0) }

Text(text = "You clicked $count times")
Button(onClick = { setCount(count + 1) }) {
    Text("Click me")
}
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun observeUser(userId: Int): User? {
    val user = remember(userId) { mutableStateOf<User?>(null) }
    DisposableEffect(userId) {
        val subscription = UserAPI.subscribeToUser(userId) {
            user.value = it
        }
        onDispose {
            subscription.unsubscribe()
        }
    }
    return user.value
}
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun LoginScreen() {
    var username by remember { mutableStateOf("user") }
    var password by remember { mutableStateOf("pass") }

    fun login() = Api.login(username, password)

    BasicTextField(
        value = username,
        onValueChange = { username = it }
    )
    BasicTextField(
        value = password,
        onValueChange = { password = it }
    )
    Button(onClick = { login() }) {
        Text("Login")
    }
}
Parameters
@NonNull T value

the initial value for the MutableState

@NonNull SnapshotMutationPolicy<@NonNull T> policy

a policy to controls how changes are handled in mutable snapshots.

neverEqualPolicy

public static final @NonNull SnapshotMutationPolicy<@NonNull T> <T extends Object> neverEqualPolicy()

A policy never treat values of a MutableState as equivalent.

Setting MutableState.value will always be considered a change. When applying a MutableSnapshot that changes the state will always conflict with other snapshots that change the same state.

produceState

@Composable
public static final @NonNull State<@NonNull T> <T extends Object> produceState(
    @NonNull T initialValue,
    @ExtensionFunctionType @NonNull SuspendFunction1<@NonNull ProduceStateScope<@NonNull T>, Unit> producer
)

Return an observable snapshot State that produces values over time without a defined data source.

producer is launched when produceState enters the composition and is cancelled when produceState leaves the composition. producer should use ProduceStateScope.value to set new values on the returned State.

The returned State conflates values; no change will be observable if ProduceStateScope.value is used to set a value that is equal to its old value, and observers may only see the latest value if several values are set in rapid succession.

produceState may be used to observe either suspending or non-suspending sources of external data, for example:

import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.produceState

val uiState by produceState<UiState<List<Person>>>(UiState.Loading, viewModel) {
    viewModel.people
        .map { UiState.Data(it) }
        .collect { value = it }
}

when (val state = uiState) {
    is UiState.Loading -> Text("Loading...")
    is UiState.Data -> Column {
        for (person in state.data) {
            Text("Hello, ${person.name}")
        }
    }
}
import androidx.compose.runtime.produceState

val currentPerson by produceState<Person?>(null, viewModel) {
    val disposable = viewModel.registerPersonObserver { person ->
        value = person
    }

    awaitDispose {
        disposable.dispose()
    }
}

produceState

@Composable
public static final @NonNull State<@NonNull T> <T extends Object> produceState(
    @NonNull T initialValue,
    Object key1,
    @ExtensionFunctionType @NonNull SuspendFunction1<@NonNull ProduceStateScope<@NonNull T>, Unit> producer
)

Return an observable snapshot State that produces values over time from key1.

producer is launched when produceState enters the composition and is cancelled when produceState leaves the composition. If key1 changes, a running producer will be cancelled and re-launched for the new source. producer should use ProduceStateScope.value to set new values on the returned State.

The returned State conflates values; no change will be observable if ProduceStateScope.value is used to set a value that is equal to its old value, and observers may only see the latest value if several values are set in rapid succession.

produceState may be used to observe either suspending or non-suspending sources of external data, for example:

import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.produceState

val uiState by produceState<UiState<List<Person>>>(UiState.Loading, viewModel) {
    viewModel.people
        .map { UiState.Data(it) }
        .collect { value = it }
}

when (val state = uiState) {
    is UiState.Loading -> Text("Loading...")
    is UiState.Data -> Column {
        for (person in state.data) {
            Text("Hello, ${person.name}")
        }
    }
}
import androidx.compose.runtime.produceState

val currentPerson by produceState<Person?>(null, viewModel) {
    val disposable = viewModel.registerPersonObserver { person ->
        value = person
    }

    awaitDispose {
        disposable.dispose()
    }
}

produceState

@Composable
public static final @NonNull State<@NonNull T> <T extends Object> produceState(
    @NonNull T initialValue,
    Object keys,
    @ExtensionFunctionType @NonNull SuspendFunction1<@NonNull ProduceStateScope<@NonNull T>, Unit> producer
)

Return an observable snapshot State that produces values over time from keys.

producer is launched when produceState enters the composition and is cancelled when produceState leaves the composition. If keys change, a running producer will be cancelled and re-launched for the new source. producer should use ProduceStateScope.value to set new values on the returned State.

The returned State conflates values; no change will be observable if ProduceStateScope.value is used to set a value that is equal to its old value, and observers may only see the latest value if several values are set in rapid succession.

produceState may be used to observe either suspending or non-suspending sources of external data, for example:

import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.produceState

val uiState by produceState<UiState<List<Person>>>(UiState.Loading, viewModel) {
    viewModel.people
        .map { UiState.Data(it) }
        .collect { value = it }
}

when (val state = uiState) {
    is UiState.Loading -> Text("Loading...")
    is UiState.Data -> Column {
        for (person in state.data) {
            Text("Hello, ${person.name}")
        }
    }
}
import androidx.compose.runtime.produceState

val currentPerson by produceState<Person?>(null, viewModel) {
    val disposable = viewModel.registerPersonObserver { person ->
        value = person
    }

    awaitDispose {
        disposable.dispose()
    }
}

produceState

@Composable
public static final @NonNull State<@NonNull T> <T extends Object> produceState(
    @NonNull T initialValue,
    Object key1,
    Object key2,
    @ExtensionFunctionType @NonNull SuspendFunction1<@NonNull ProduceStateScope<@NonNull T>, Unit> producer
)

Return an observable snapshot State that produces values over time from key1 and key2.

producer is launched when produceState enters the composition and is cancelled when produceState leaves the composition. If key1 or key2 change, a running producer will be cancelled and re-launched for the new source. producer should use ProduceStateScope.value to set new values on the returned State.

The returned State conflates values; no change will be observable if ProduceStateScope.value is used to set a value that is equal to its old value, and observers may only see the latest value if several values are set in rapid succession.

produceState may be used to observe either suspending or non-suspending sources of external data, for example:

import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.produceState

val uiState by produceState<UiState<List<Person>>>(UiState.Loading, viewModel) {
    viewModel.people
        .map { UiState.Data(it) }
        .collect { value = it }
}

when (val state = uiState) {
    is UiState.Loading -> Text("Loading...")
    is UiState.Data -> Column {
        for (person in state.data) {
            Text("Hello, ${person.name}")
        }
    }
}
import androidx.compose.runtime.produceState

val currentPerson by produceState<Person?>(null, viewModel) {
    val disposable = viewModel.registerPersonObserver { person ->
        value = person
    }

    awaitDispose {
        disposable.dispose()
    }
}

produceState

@Composable
public static final @NonNull State<@NonNull T> <T extends Object> produceState(
    @NonNull T initialValue,
    Object key1,
    Object key2,
    Object key3,
    @ExtensionFunctionType @NonNull SuspendFunction1<@NonNull ProduceStateScope<@NonNull T>, Unit> producer
)

Return an observable snapshot State that produces values over time from key1, key2 and key3.

producer is launched when produceState enters the composition and is cancelled when produceState leaves the composition. If key1, key2 or key3 change, a running producer will be cancelled and re-launched for the new source. [producer should use ProduceStateScope.value to set new values on the returned State.

The returned State conflates values; no change will be observable if ProduceStateScope.value is used to set a value that is equal to its old value, and observers may only see the latest value if several values are set in rapid succession.

produceState may be used to observe either suspending or non-suspending sources of external data, for example:

import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.produceState

val uiState by produceState<UiState<List<Person>>>(UiState.Loading, viewModel) {
    viewModel.people
        .map { UiState.Data(it) }
        .collect { value = it }
}

when (val state = uiState) {
    is UiState.Loading -> Text("Loading...")
    is UiState.Data -> Column {
        for (person in state.data) {
            Text("Hello, ${person.name}")
        }
    }
}
import androidx.compose.runtime.produceState

val currentPerson by produceState<Person?>(null, viewModel) {
    val disposable = viewModel.registerPersonObserver { person ->
        value = person
    }

    awaitDispose {
        disposable.dispose()
    }
}

referentialEqualityPolicy

public static final @NonNull SnapshotMutationPolicy<@NonNull T> <T extends Object> referentialEqualityPolicy()

A policy to treat values of a MutableState as equivalent if they are referentially (===) equal.

Setting MutableState.value to its current referentially (===) equal value is not considered a change. When applying a MutableSnapshot, if the snapshot changes the value to the equivalent value the parent snapshot has is not considered a conflict.

rememberUpdatedState

@Composable
public static final @NonNull State<@NonNull T> <T extends Object> rememberUpdatedState(@NonNull T newValue)

remember a mutableStateOf 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:

import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState

@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()
        }
    }
}

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:

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState

@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)
        }
    }

    // ...
}

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

setValue

public static final void <T extends Object> setValue(
    @NonNull MutableState<@NonNull T> receiver,
    Object thisObj,
    @NonNull KProperty<@NonNull ?> property,
    @NonNull T value
)

Permits property delegation of vars using by for MutableState.

import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var count by remember { mutableStateOf(0) }

Text(text = "You clicked $count times")
Button(onClick = { count = count + 1 }) {
    Text("Click me")
}

snapshotFlow

public static final @NonNull <Error class: unknown class><@NonNull T> <T extends Object> snapshotFlow(@NonNull Function0<@NonNull T> block)

Create a Flow from observable Snapshot state. (e.g. state holders returned by mutableStateOf.)

snapshotFlow creates a Flow that runs block when collected and emits the result, recording any snapshot state that was accessed. While collection continues, if a new Snapshot is applied that changes state accessed by block, the flow will run block again, re-recording the snapshot state that was accessed. If the result of block is not equal to the previous result, the flow will emit that new result. (This behavior is similar to that of kotlinx.coroutines.flow.distinctUntilChanged.) Collection will continue indefinitely unless it is explicitly cancelled or limited by the use of other Flow operators.

import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshotFlow

// Define Snapshot state objects
var greeting by mutableStateOf("Hello")
var person by mutableStateOf("Adam")

// ...

// Create a flow that will emit whenever our person-specific greeting changes
val greetPersonFlow = snapshotFlow { "$greeting, $person" }

// ...

val collectionScope: CoroutineScope = TODO("Use your scope here")

// Collect the flow and offer greetings!
collectionScope.launch {
    greetPersonFlow.collect {
        println(greeting)
    }
}

// ...

// Change snapshot state; greetPersonFlow will emit a new greeting
Snapshot.withMutableSnapshot {
    greeting = "Ahoy"
    person = "Sean"
}

block is run in a read-only Snapshot and may not modify snapshot data. If block attempts to modify snapshot data, flow collection will fail with IllegalStateException.

block may run more than once for equal sets of inputs or only once after many rapid snapshot changes; it should be idempotent and free of side effects.

When working with Snapshot state it is useful to keep the distinction between events and state in mind. snapshotFlow models snapshot changes as events, but events cannot be effectively modeled as observable state. Observable state is a lossy compression of the events that produced that state.

An observable event happens at a point in time and is discarded. All registered observers at the time the event occurred are notified. All individual events in a stream are assumed to be relevant and may build on one another; repeated equal events have meaning and therefore a registered observer must observe all events without skipping.

Observable state raises change events when the state changes from one value to a new, unequal value. State change events are conflated; only the most recent state matters. Observers of state changes must therefore be idempotent; given the same state value the observer should produce the same result. It is valid for a state observer to both skip intermediate states as well as run multiple times for the same state and the result should be the same.

structuralEqualityPolicy

public static final @NonNull SnapshotMutationPolicy<@NonNull T> <T extends Object> structuralEqualityPolicy()

A policy to treat values of a MutableState as equivalent if they are structurally (==) equal.

Setting MutableState.value to its current structurally (==) equal value is not considered a change. When applying a MutableSnapshot, if the snapshot changes the value to the equivalent value the parent snapshot has is not considered a conflict.

toMutableStateList

public static final @NonNull SnapshotStateList<@NonNull T> <T extends Object> toMutableStateList(@NonNull Collection<@NonNull T> receiver)

Create an instance of MutableList from a collection that is observable and can be snapshot.

toMutableStateMap

public static final @NonNull SnapshotStateMap<@NonNull K, @NonNull V> <K extends Object, V extends Object> toMutableStateMap(
    @NonNull Iterable<@NonNull Pair<@NonNull K, @NonNull V>> receiver
)

Create an instance of MutableMap from a collection of pairs that is observable and can be snapshot.