Effect Handlers in JetPack Compose : A Deep Dive
What are the Side Effects of Jetpack Compose?
While working with Composable Functions, they often get recomposed on a change of state. When Functions propose it might update some data that is not in the cope of the composable functions. Such Scenarios are called Side Effects. For e.g. Making a network call inside a Compose Function which might get Recomposed when some state of Compose function changes.
In the following example when we click on the Increment Button to increment the counter, the API getCategoryList() is invoked every time due Recomposition of Compose Function. Hence, leading to a side effect.

Side Effect Sample
Types of Effect Handlers
Jetpack compose provides solutions to these side effects using multiple types of effect handlers that we will understand briefly.

Effect Handlers Types
Launched Effect
LaunchedEffect is a composable function that is used to launch a coroutine inside the scope of composable. When LaunchedEffect enters the composition, it launches a coroutine and cancels when it leaves the composition. This is useful for performing side effects, such as making network calls or updating a database, without blocking the UI thread.
It takes 2 parameters:
- A key1 parameter that decides when the Lambda function inside it will execute
- Lambda Function to be Executed.
In the below example assuming that getCategoryList() is a network call, this should be invoked inside LaunchedEffect to avoid calling the Network API multiple times even if Recomposition happens.

Launched effect Example
Remember Coroutine Scope
Launched Effect launches on the first composition, so we can use it as is. But to have manual control over the launch, use rememberCoroutineScope instead. It gives lifecycle-aware scope which can be used to launch a coroutine inside it. The scope is cancelled when the call leaves the composition making it lifecycle-aware.
In the below example, Remember Coroutine scope is used which will be launched at the click of a button and it will also provide a Coroutine scope for executions in the background.

RememberCoroutineScope
Disposable Effect
Disposable Effect is similar to Launch Effect which is also executed on the key1 parameter. It consists of the onDispose() method which can be used for any clean-up tasks. For e.g. Removing some callbacks/ listeners. We use onDispose to dispose of disposable and stop the operation when the Composable is removed.
In the below example, we are removing the observer from the lifecycle owner using the onDispose() method of DisposableEffect.

Disposable Sample
Remember Updated State
LaunchedEffect restart when one of the value of the key parameters get updated. But sometimes we want to capture the changed value inside the effect without restarting it. This process is helpful if we have long-running option that is expensive to restart. In this use case, we use Remember Updated State Effect Handler to have the updated state of the variable even if the Launched Effect is restarted.

RememberUpdatedState Example

Without RememberUpdatedState Logs

Using Remember state Logs
In the above example, we are sending the updated counter value inside a LaunchedEffect after a delay of 2 seconds. In CounterText composable the counter value(without updated state) passed by Parent composable is used before and after a delay of 5 seconds. Inside the LanchedEffect of child composable, the updated counter value (10) will not be printed because it was launched with an initial counter value of 0. If we change the counter value to be used as Updated State the state of the counter will also updated post 5 seconds of delay in the Child composable. Hence this can be used if we need the updated state event after long-running operations is completed.
DerivedStateOf
derivedStateOf is a composable that can be used to derive a new state based on the values of other state variables. It is useful when you need to compute a value that depends on other values, and you want to avoid recomputing the value unnecessarily.
In the below example, we are deducing the Background color of the Counter text using counter state. Where if the counter is divisible by 2 then the Green color else Red Colour.

DervivedStateExample
ProduceState
produceState converts non-compose state into compose state. The producer is started when produce state enters the Composition and is stopped when it leaves the Composition. It launches a coroutine scoped to the composition that can push values into a returned state. With the Produce state we just need to provide the initial state of composition and lambda of what will be produced as a state and can be directly used in the compose function.

ProduceStateExample
Conclusion
Through this comprehensive guide, we can develop a basic understanding the of Side effects of composition and the ways to handle them. This will be useful when Apps are implemented on a large scale using Jetpack Compose.