Yurowitz
Yurowitz

Reputation: 1396

How to make LaunchedEffect run once and never again?

I know that LaunchedEffect(key) is executed when composition starts, and is also cancelled and re-executed again when the key changes. However, I want it to be executed only once and never again, I am using the following workaround but I feel like I am missing something:

if (!launchedBefore) {
   LaunchedEffect(null) {
      //stuff

      launchedBefore = true
   }
}

The code above works just fine. But it feels like a stretched workaround while something much simpler can be done. Am I misunderstanding how LaunchedEffect fully works?

I tried using null and Unit as keys cuz they never changed, but the code is executed every time a composition takes place.

Upvotes: 8

Views: 11857

Answers (3)

uragiristereo
uragiristereo

Reputation: 874

I usually pass a longer-living variable for the key, something like ViewModel. It will only executed when the ViewModel is being initialized. Or using remembered saveable boolean may do the trick.

val bool = rememberSaveable { true }

LaunchedEffect(key1 = bool) {
    // do something
}

Upvotes: 1

Nikola Despotoski
Nikola Despotoski

Reputation: 50538

The problem is not in the LaunchEffect or its key parameter, but in the upper composable. The upper composable is getting recomposed. Probably you should display more details how the LaunchEffect is called and calling sites.

Recomposition looks up for nearest composable that could have been affected by the change.

Upvotes: 2

deluxe1
deluxe1

Reputation: 857

LaunchedEffect(Unit) should execute only once when the composition starts. The only time it would get re-executed during recomposition is if it gets removed from the view tree during one of the previous recompositions. An example would be if you have it within a condition whose value changes at some point (in an if block, when block or any other conditional statement).

I would assume that the problem with recomposing lies in the other part of the code that is not shown in your snippet. Check if the LaunchedEffect is nested in a conditional block that might cause it to get executed after a recomposition.

Upvotes: 14

Related Questions