kotlinandroid-jetpack-composeside-effects

what is DisposableEffect and under the hood in jetpack compose?


I've been trying to understand what is DisposableEffect and How it works for a while so I have searched on the internet for this and I saw that most of the documentation are similar explanation for example

DisposableEffect is a powerful tool provided by Jetpack Compose that allows you to perform side effects in your composable functions that need to be cleaned up when the composable leaves the composition. You can use keys to control when the callback function is called.

I know that DisposableEffect works asynchronously like LaunchedEffect and based on key values but when onDispose method works as you can see the definition of above

that need to be cleaned up when the composable leaves the composition

This sentence probably defines the onDispose method, so in this case, it means onDispose will work, but what does it mean when the composable leaves the composition is written like this everywhere? I couldn't understand.

I did it like this for example

State

data class State(
    ...
    val isError:Int?=null,
    ...
)

UI

val errMsg = stringResource(id = R.string.error)
val savedMsg = stringResource(id = R.string.saved)

DisposableEffect(state.isError) {
        when (state.isError) {
            0 -> Toast.makeText(context, savedMsg, Toast.LENGTH_LONG).show()
            1 -> Toast.makeText(context, errMsg, Toast.LENGTH_LONG).show()
            else -> {}
        }
        onDispose {
            setIsError()
        }
    }

VM

  fun setIsError(){
    _state.update {
        it.copy(
            isError = null,
        )
    }
}
 

So when does on Dispose run for example ?

That's why I used onDisposableEffect here every time the user presses a button, if the operation is successful when the button is pressed, isError 0 comes, if not 1, I want to get a Success message in every successful operation, but once the button is pressed and the operation is successful, the Success message does not work because the key value is isError is still same 0, so I used DisposableEffect to achieve that problem but as I said I don't know the detailed and I did not fully understand


Solution

  • Consider this example code:

    @Composable
    fun example() {
      var inComposition by remember { mutableStateOf(true) }
      if (inComposition) {
        DisposableEffect {
          ...
        }
      }
    }
    

    The DisposableEffect will leave the composition, and thus run its onDispose function, when the inComposition variable goes from true to false.