Reputation: 60081
We have the below compose which works well.
@Composable
fun MyInnerControl() {
var timerStartStop by remember { mutableStateOf(true) }
Button(onClick = {
timerStartStop = !timerStartStop
}) {
Text(if (timerStartStop) "Stop" else "Start")
}
}
But if we have the timerStartStop
passed through the function parameter, I cannot do as below
@Composable
fun MyInnerControl(timerStartStop: Boolean) {
Button(onClick = {
timerStartStop = !timerStartStop
}) {
Text(if (timerStartStop) "Stop" else "Start")
}
}
I can pass as below, but then I have to change my timerStartStop
to timerStartStop.value
@Composable
fun MyInnerControl(timerStartStop: MutableState<Boolean>) {
Button(onClick = {
timerStartStop.value = !timerStartStop.value
}) {
Text(if (timerStartStop.value) "Stop" else "Start")
}
}
Is there any way to have the MutableState<Boolean>
passed over the argument, yet within the function we can use the delegate approach, i.e. using timerStartStop
instead of timerStartStop.value
?
Upvotes: 2
Views: 911
Reputation: 1023
I think it's better to apply proper state hoisting methods and give MyInnerControl
the ability to both read and edit the parameter in the following way.
@Composable
fun ParentComposable() {
val isTimerRunning by remember { mutableStateOf(false) } }
MyInnerControl(
isTimerRunning = isTimerRunning,
flipTimerState {
isTimerRunning = !isTimerRunning
}
}
}
@Composable
fun MyInnerControl(
isTimerRunning: Boolean,
flipTimerState: () -> Unit,
) {
Button(
onClick = { flipTimerState() }
) {
Text(if (isTimerRunning) "Stop" else "Start")
}
}
Upvotes: 0
Reputation: 46
Jetpack Compose tells you to respect Single Source of Truth principle, which means that you can not pass state as argument if you want to change that state inside your function.
So generally you have to choose one of two approaches:
@Composable
fun MyInnerControl(timerStartStop: Boolean, onClick: ()->Unit) {
Button(onClick = onClick) {
Text(if (timerStartStop) "Stop" else "Start")
}
}
@Composable
fun MyInnerControl() {
var timerStartStop by remember { mutableStateOf(true) }
Button(onClick = {
timerStartStop = !timerStartStop
}) {
Text(if (timerStartStop) "Stop" else "Start")
}
}
Upvotes: 3