https://kotlinlang.org logo
Title
d

Daniel Okanin

08/08/2022, 6:05 PM
Hi everyone! Im trying to count my onClick events in my composable function and overload this counter on callback. So I define var counter = remember{0} But this counter is reset always. I dont want to define the counter as remember{mutableSatateOf(0)} becuase by increase the counter I dont want to trigger recomposition. So how can I define remember parameter that not override by recompostion ?
f

Francesc

08/08/2022, 7:03 PM
define the counter in your viewmodel and add a method in your viewmodel to increment the counter, which you call from the click listener
s

Stylianos Gakis

08/08/2022, 7:30 PM
Why do you not want to trigger recomposition? Are you using that value in order to render some UI? If you are, why would you not want to recompose?
d

Daniel Okanin

08/08/2022, 7:43 PM
@Stylianos Gakis I don’t need to render any UI, just count click events and overload on callback. @Francesc So we cant define, in composable function, remember parameter which save between recompositions and not trigger recomposition by update?
s

Stylianos Gakis

08/08/2022, 7:51 PM
If you don’t read the state in composition then maybe what you want is as Francesc said to move that value outside of your composable, potentially in your VM and do whatever it is there. I don’t quite understand what you mean by “and overload on callback” if you could add some code snippet it’d help me I think. As far as saving something in composition which does not trigger recompositions, yes you can, if you simply have a
val x by remember { mutableSatateOf(0) }
and you never read that
x
inside composition then it won’t trigger a recomposition. It only does so if you’re reading that value somewhere in composition. That’s also how if you only read the value in a “smaller” scope you get the smarter recomposition where only that specific scope gets recomposed as opposed to the scope in which the
mutableStateOf
is defined. Just make sure you don’t do the
val (x, setX) = remember { mutableStateOf(0) }
syntax as that one does indeed read the value and therefore triggers recompositions at that level every time the state changes.
d

Daniel Okanin

08/08/2022, 8:19 PM
@Stylianos Gakis Somthing like this: Im trying to do a generic functionalty common to some screen so I want to keep the counter updates in the composable function and not in VM
var counter = remember {0}
    Column(modifier = modifier
        .fillMaxWidth()
        .clickable(
            onClick = { onClickEventListener?.onClick(++counter) },
            indication = rememberRipple(),
            interactionSource = remember { MutableInteractionSource() }
        )
    )
f

Francesc

08/08/2022, 8:20 PM
for this use case it doesn't make sense to define the counter within the scope of the composable
d

Daniel Okanin

08/08/2022, 8:26 PM
@Francesc Even if it a common composable used in multiple places (screen)?
f

Francesc

08/08/2022, 8:28 PM
yes, even then. This composable doesn't do anything with the counter, so it shouldn't know about it. It should just get a lambda for the click listener and call it - that's as far as its involvement should be. The fact that clicking the button triggers a counter increase is something this composable does not need to know and should not know
if you make it take a lambda then it is automatically reusable