Masoud Karimi
11/09/2023, 6:54 PMColumn {
var counter by mutableIntStateOf(0)
Button(onClick = { counter++ }) {
Text(text = "Counter $counter")
}
// Text(text = "Counter $counter")
}
If I comment the Text the counter will be increased whenever I click on the button. But when I uncomment it the counter is always 0. I think that's because the Text composable is in the main scope of the parent composable function whenever it changes the whole function is recomposed and the counter is reset to 0. Am I thinking correctly or missing something here?Stylianos Gakis
11/09/2023, 7:05 PMStylianos Gakis
11/09/2023, 7:05 PMascii
11/09/2023, 7:06 PMStylianos Gakis
11/09/2023, 7:06 PMremember
it as you should.ascii
11/09/2023, 7:09 PMStylianos Gakis
11/09/2023, 8:56 PMmutable{{Int/Float/..}}StateOf
while it does mutableStateOf
calls?
In any case, it’s not a compilation error to do this wrong, you just don’t get the right behaviorshikasd
11/09/2023, 9:15 PMMasoud Karimi
11/10/2023, 11:39 AMMasoud Karimi
11/10/2023, 11:40 AMStylianos Gakis
11/10/2023, 11:40 AMMasoud Karimi
11/10/2023, 11:42 AMText
Composable, the counter won't increase any moreStylianos Gakis
11/10/2023, 11:43 AMStylianos Gakis
11/10/2023, 11:50 AMColumn { < -
var counter by mutableIntStateOf(0) |
Button(onClick = { counter++ }) { < - |
Text(text = "Counter $counter") | inner scope #2 | outer scope, #1
} < - |
|
// Text(text = "Counter $counter") |
} < -
You got the mutableState defined in scope #1. That does not mean much by itself, for compose to determine when something will recompose, it needs to be reading the mutable state.
In the commented out situation:
The only place where you read the state is inside scope #2. That means that when the mutableState changes, scope #2 is listening on those changes, since you are using it there, and when it changes it recomposes the Button lambda.
In the situation where you do not have the other text commented out:
Then you are reading counter
both in scope #2 and in scope #1. That means when mutableState changes, both scope #1 and scope #2 see the change, and they decide to recompose themselves. When that happens however now, since we are inside scope #1 and it is being recomposed, the line var counter by mutableIntStateOf(0)
is run again, so the mutableState is set to 0
again.
And that’s it, this is what you are observing here.
Interestingly! If Button
was an inline
function, then the scope #2 would simply not exist, it’d all be one recomposition scope. Which would mean you would see the second behavior regardless on if you have the other Text
which is reading the counter
mutableState or notMasoud Karimi
11/10/2023, 12:01 PMText
in another Button
because Button is not inlined, and the counter increases whenever I click on each button. And that makes sense. Thank u again for great explanation. 👍Stylianos Gakis
11/10/2023, 12:07 PMmutableState
defined inside a @Composable function. That’s the verdict you should get out of this discussion.Masoud Karimi
11/10/2023, 12:14 PM