Home > front end >  How to have only one LaunchedEffect runnin in Kotlin/Compose
How to have only one LaunchedEffect runnin in Kotlin/Compose

Time:08-29

I have a cookie clicker rip off app about beans in Kotlin and Compose. I have a LaunchedEffect running a timer that updates the amount of beans every second. The only problem is that I never stop the LaunchedEffect timer, so every time I execute the code, it creates another one leading to many timers adding many beans. A code snippet is below showing the code I am talking about.

if (showHome) {
        val updateAmount by remember { mutableStateOf((greenBeans)   (10 * kidneyBeans)   (100 * coffeeBeans)   (1000 * pintoBeans)   (10000 * chocolateBeans)   (100000 * jellyBeans))}

        LaunchedEffect(key1 = true) {
            updateBeans {
                beans  = updateAmount
            }
        }
}

Is there a way to prevent this problem from occurring?

CodePudding user response:

The LaunchedEffect itself is a composable, so every time the LaunchedEffect leave your compose scope, change screen, or etc. It will got cancelled.

Simple example is your code, when the showHome is set to false, then the LaunchedEffect leave composition and got destroyed. It will only started again when the showHome is set to true

CodePudding user response:

The thing with your code is your conditional code block enters recomposition when showHome is true and creates a new LaunchedEffect and updateAmount

if (showHome) {
   // Anything here is recomposed when it toggle
}

Anything inside this block enters composition if showHome is true initially and on every recomposition updateAmount changes from false to true. You might want to move updateAmount outside of if block for starters.

If you don't want to trigger a timer every time showHome is true

you might have it something Like

LaunchedEffect(key1 = true) {
    if (showHome) {
        updateBeans {
            beans  = updateAmount
        }
    }
}

With the snippet above LaunchedEffect will be launched once but update only when showHome is true.

If you want to reset timer every time you set showHome true you can use it as

LaunchedEffect(key1 = showHome) {
    if (showHome) {
        updateBeans {
            beans  = updateAmount
        }
    }
}
  • Related