DisposableEffect

Composable Function

Common

Deprecated DisposableEffectNoParamError

@Composable
public fun DisposableEffect(effect: DisposableEffectScope.() -> DisposableEffectResult): Unit

A side effect of composition that must be reversed or cleaned up if the DisposableEffect leaves the composition.

It is an error to call DisposableEffect without at least one key parameter.

Common
@Composable
public fun DisposableEffect(
    key1: Any?,
    effect: DisposableEffectScope.() -> DisposableEffectResult,
)

A side effect of composition that must run for any new unique value of key1 and must be reversed or cleaned up if key1 changes or if the DisposableEffect leaves the composition.

A DisposableEffect's key is a value that defines the identity of the DisposableEffect. If a key changes, the DisposableEffect must dispose its current effect and reset by calling effect again. Examples of keys include:

  • Observable objects that the effect subscribes to
  • Unique request parameters to an operation that must cancel and retry if those parameters change

DisposableEffect may be used to initialize or subscribe to a key and reinitialize when a different key is provided, performing cleanup for the old operation before initializing the new. For example:

A DisposableEffect must include an onDispose clause as the final statement in its effect block. If your operation does not require disposal it might be a SideEffect instead, or a LaunchedEffect if it launches a coroutine that should be managed by the composition.

There is guaranteed to be one call to dispose for every call to effect. Both effect and dispose will always be run on the composition's apply dispatcher and appliers are never run concurrent with themselves, one another, applying changes to the composition tree, or running RememberObserver event callbacks.

Common
@Composable
public fun DisposableEffect(
    key1: Any?,
    key2: Any?,
    effect: DisposableEffectScope.() -> DisposableEffectResult,
)

A side effect of composition that must run for any new unique value of key1 or key2 and must be reversed or cleaned up if key1 or key2 changes, or if the DisposableEffect leaves the composition.

A DisposableEffect's key is a value that defines the identity of the DisposableEffect. If a key changes, the DisposableEffect must dispose its current effect and reset by calling effect again. Examples of keys include:

  • Observable objects that the effect subscribes to
  • Unique request parameters to an operation that must cancel and retry if those parameters change

DisposableEffect may be used to initialize or subscribe to a key and reinitialize when a different key is provided, performing cleanup for the old operation before initializing the new. For example:

A DisposableEffect must include an onDispose clause as the final statement in its effect block. If your operation does not require disposal it might be a SideEffect instead, or a LaunchedEffect if it launches a coroutine that should be managed by the composition.

There is guaranteed to be one call to dispose for every call to effect. Both effect and dispose will always be run on the composition's apply dispatcher and appliers are never run concurrent with themselves, one another, applying changes to the composition tree, or running RememberObserver event callbacks.

Common
@Composable
public fun DisposableEffect(
    key1: Any?,
    key2: Any?,
    key3: Any?,
    effect: DisposableEffectScope.() -> DisposableEffectResult,
)

A side effect of composition that must run for any new unique value of key1, key2 or key3 and must be reversed or cleaned up if key1, key2 or key3 changes, or if the DisposableEffect leaves the composition.

A DisposableEffect's key is a value that defines the identity of the DisposableEffect. If a key changes, the DisposableEffect must dispose its current effect and reset by calling effect again. Examples of keys include:

  • Observable objects that the effect subscribes to
  • Unique request parameters to an operation that must cancel and retry if those parameters change

DisposableEffect may be used to initialize or subscribe to a key and reinitialize when a different key is provided, performing cleanup for the old operation before initializing the new. For example:

A DisposableEffect must include an onDispose clause as the final statement in its effect block. If your operation does not require disposal it might be a SideEffect instead, or a LaunchedEffect if it launches a coroutine that should be managed by the composition.

There is guaranteed to be one call to dispose for every call to effect. Both effect and dispose will always be run on the composition's apply dispatcher and appliers are never run concurrent with themselves, one another, applying changes to the composition tree, or running RememberObserver event callbacks.

Common
@Composable
public fun DisposableEffect(
    vararg keys: Any?,
    effect: DisposableEffectScope.() -> DisposableEffectResult,
)

A side effect of composition that must run for any new unique value of keys and must be reversed or cleaned up if any keys change or if the DisposableEffect leaves the composition.

A DisposableEffect's key is a value that defines the identity of the DisposableEffect. If a key changes, the DisposableEffect must dispose its current effect and reset by calling effect again. Examples of keys include:

  • Observable objects that the effect subscribes to
  • Unique request parameters to an operation that must cancel and retry if those parameters change

DisposableEffect may be used to initialize or subscribe to a key and reinitialize when a different key is provided, performing cleanup for the old operation before initializing the new. For example:

A DisposableEffect must include an onDispose clause as the final statement in its effect block. If your operation does not require disposal it might be a SideEffect instead, or a LaunchedEffect if it launches a coroutine that should be managed by the composition.

There is guaranteed to be one call to dispose for every call to effect. Both effect and dispose will always be run on the composition's apply dispatcher and appliers are never run concurrent with themselves, one another, applying changes to the composition tree, or running RememberObserver event callbacks.

Code Examples

disposableEffectSample

fun disposableEffectSample() {
    @Composable
    fun UserProfile(userRepository: UserRepository, userRequest: UserDataRequest) {
        var userDataState by remember { mutableStateOf<UserDataState>(UserDataState.Loading) }
        // If either the repository or request change, we must cancel our old data fetch
        // and begin a new data fetch. We will cancel the current data fetch if UserProfile
        // leaves the composition.
        DisposableEffect(userRepository, userRequest) {
            val requestDisposable =
                userRepository.fetchUserData(
                    userRequest,
                    onSuccess = { response -> userDataState = UserDataState.UserData(response) },
                    onError = { throwable ->
                        userDataState = UserDataState.Error(throwable.message)
                    },
                )
            onDispose { requestDisposable.dispose() }
        }
        // ...
    }
}