I'm working on an application using Jetpack Compose, and I've encountered an issue that's puzzling me. Every time I change the value of a TextField, all composables in my user interface are recomposed, even those not directly related to the TextField.
@Composable
fun Test(
viewModel: TestViewModel = hiltViewModel()
) {
val state = viewModel.state
Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center) {
TextField(modifier = Modifier.fillMaxWidth(), value = state.address, onValueChange = {
viewModel.updateAddress(it)
})
Spacer(modifier = Modifier.height(12.dp))
TextField(modifier = Modifier.fillMaxWidth(), value = state.address2, onValueChange = {
viewModel.updateAddress2(it)
})
Spacer(modifier = Modifier.height(12.dp))
TextField(modifier = Modifier.fillMaxWidth(), value = state.address3, onValueChange = {
viewModel.updateAddress3(it)
})
}
}
@HiltViewModel
class TestViewModel @Inject constructor() : ViewModel() {
var state by mutableStateOf(TestState())
private set
fun updateAddress(address: String) {
state = state.copy(
address = address
)
}
fun updateAddress2(address: String) {
state = state.copy(
address2 = address
)
}
fun updateAddress3(address: String) {
state = state.copy(
address3 = address
)
}
}
data class TestState(
val address: String = "",
val address2: String = "",
val address3: String = "",
)
I suspect that the issue may be related to the following code snippet:
state = state.copy(
address = address
)
What would be the best solution for a large project?
I appreciate any help or guidance you can provide.
The inspector is showing these function as recomposing as all but one of the TextField
s is being called with the same parameters it will be skipped and will return immediately.
You can verify this in the debugger by stepping into TextField
for the versions that are not changing and validate that function just checks the parameters you passed are the same as last time and then returns.