1

I have the following Android Jetpack Compose component:

@Composable
fun TestScreen(){

    println("inside-TestScreen()")
    
    var number by remember{ mutableStateOf(1) }

    Button(onClick = { number++ }) {

        println("inside-Button()")
        
        Column {

            println("inside-Column()")
            
            Text("Hello $number")

        }

    }

}

When it's composed, the following is logged:

inside-TestScreen()
inside-Button()
inside-Column()

This works as I expect. However, when I click on the Button (i.e. changes the state variable number), a recomposition happens, and the following is logged:

inside-Button()
inside-Column()

Apparently, the Button content is recomposed, and I don't understand why. The Button content does not use the number variable, so I thought Jetpack Compose would be smart enough to understand that the Button content wouldn't need to recompose. I thought only the Column content would recompose, and only inside-Column() would be logged.

Why does the content of the Button recompose even though it has no dependency on a state that changed?

Peppe L-G
  • 7,351
  • 2
  • 25
  • 50

1 Answers1

2

Because Column, Box, Row and any Composable that is inline and returns Unit does not create a scope. When recomposition happens Jetpack Compose checks out closest scope to recompose which is content of Button in your exmple.

You can refer these answers for more details and the articles in first link.

Jetpack Compose Smart Recomposition

Why does mutableStateOf without remember work sometimes?

Thracian
  • 43,021
  • 16
  • 133
  • 222
  • Thanks! You don't happen to have a link to the docs that explains this? I think I've read most of what's written at developer.android.com without having got this understanding, and when I search through the pages there now I can't find anything about this either. Am curios about why one would want an inline component, and how to find out which components that are inline, etc. – Peppe L-G Mar 25 '23 at 17:49
  • 1
    I found it by investigating source code of Column and others, then i came across Vinay Gaba's article. I assume, based on the tweet and other resources and how inline works with lamdad in Kotlin, purpose of having an `inline` Composable is not to create new lambda instance on each recomposition and keeping call site in same level as child Composables. I haven't seen any official about this or about @Stable and @Immutable as well but searching these you can find good documents about that subject as will which is also good part of scoping recomposition – Thracian Mar 25 '23 at 18:17
  • https://kotlinlang.org/docs/inline-functions.html – Thracian Mar 25 '23 at 18:19