Reputation: 436
I try to use mutable object in compose function:
@Composable
fun TextFieldComponent(
name: MutableState<String>,
nameErrorState: MutableState<Boolean>,
modifier: Modifier = Modifier
)
I use MutableState
because it is field for input data.
It works good.
But I check my code with detectAll
And it shows me error:
Using mutable objects as state in Compose will cause your users to see incorrect or stale data in your app.
Mutable objects that are not observable, such as ArrayList or a mutable data class, cannot be observed by
Compose to trigger recomposition when they change.
See https://twitter.github.io/compose-rules/rules/#do-not-use-inherently-mutable-types-as-parameters for more information. [MutableParams]
I have read info from this link but still don't understand, how should I use it.
Upvotes: 1
Views: 692
Reputation: 11082
As a standard rule, you shouldn't have a mutable state as a parameter to a composable function. Because, in Kotlin arguments are immutable by design. If you wish to change the state of a variable within the composable, you can have muttable state of local variable for that.
@Composable
fun Profile(initName: String) {
var name by rememberSaveable { mutableStateOf(initState) }
TextFieldComponent(
name,
nameErrorState = name.isEmpty(),
modifier = Modifier.padding(top = 16.dp),
onNameChanged = { newValue -> name = newValue})
}
}
Upvotes: 2
Reputation: 2705
You should pass the data and callback to change it:
@Composable
fun TextFieldComponent(
name: String,
nameErrorState: Boolean,
modifier: Modifier = Modifier,
onNameChanged: ((String) -> Unit) = {}
)
This way TextFieldComponent is always redrawn when the name is changed. You can also pass name as mutable data from outer Composable:
@Composable
fun Content() {
var name by remember { mutableStateOf("") }
TextFieldComponent(
name,
nameErrorState = name.isEmpty(),
modifier = Modifier.padding(top = 16.dp),
onNameChanged = { newValue -> name = newValue})
}
Upvotes: 2