A Guide to DisposableEffect in Compose

Anand Jeyapal
3 min readFeb 26, 2024
// If `key1 or key2` changes, dispose and reset the effect
DisposableEffect(key1, key2) {
doStuff()
// When the effect leaves the Composition, remove the observer
onDispose {
doCleanup()
}
}

DisposableEffect is one of the side effects in Jetpack compose. It has an additional method called ‘onDispose’

This onDispose method will be called in the following situations,

  1. When the keys of DisposableEffect are changed.
  2. When the enclosing composable leaves the composition.

Let’s create a Composable which shows a Button at the center of a column.

@Composable
fun Screen() {
Column(
Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(onClick = { }) {
Text(“I was clicked 0 times”)
}
}
}

Create a mutableState for the count which is displayed in Button composable.

var count by remember { mutableIntStateOf(0)}
Button(onClick = {  }) {
Text("I was clicked $count times")
}

Update the onClick of the Button. On clicking the button, count will be increased like below.

Button(onClick = { count += 1 }) {

Since the state is changed, recomposition would happen and it re-renders the Button composable.

Now create a disposable effect that listens this count

        // If `count` changes, dispose and reset the effect
DisposableEffect(count) {
Log.d("AAA", "I am doing some stuff")
// When the effect leaves the Composition, run onDispose
onDispose {
Log.d("AAA", "I am cleaning the mess")
}
}

The final code would look like below

@Composable
fun Screen() {
var count by remember { mutableIntStateOf(0) }
Column(
Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(onClick = { count += 1 }) {
Text("I was clicked $count times")
}
// If `textToDisplay` changes, dispose and reset the effect
DisposableEffect(count) {
Log.d("AAA", "I am doing some stuff")
// When the effect leaves the Composition, run onDispose
onDispose {
Log.d("AAA", "I am cleaning the mess")
}
}
}
}

During the initial render, the following things would happen,

  1. A column with a button at center would render.
  2. DisposableEffect would be called.

When the button is clicked, the following things would happen

  1. It changes the value of count.
  2. count is a state, it will trigger the recomposition.
  3. On recomposition, DisposableEffect leaves the composition and re-enters; hence onDispose will be called and the effect will be called again

Conclusion

SideEffect is a very helpful concept in compose for complex resource management. It needs to be used wisely.

Generally it is recommended to not have side effects when there is lot of recompositions possible. (DisposableEffect would be called on every re-composition)

References : https://developer.android.com/jetpack/compose/side-effects#disposableeffect

Thanks for reading the article, Give applause if you really like it as it means a lot to me. :)

--

--