Unnecessary Recomposition of Composables when Changing TextField Value in Jetpack Compose

136 Views Asked by At

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 = "",
)

Screen

Layout Inspector

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.

1

There are 1 best solutions below

0
On

The inspector is showing these function as recomposing as all but one of the TextFields 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.