Reputation: 251
I will describe my problem and then I'll provide my implementation.
I have a viewModel with a variable connectionStatus
that stores the value that tracks the connectionStatus of a "device", and changes when the connection status of the device changes.
I display the conneciton status in a Text composable. below the text cmposable, I also have a button "cancel connection", which calls the cancelConnection method in the viewModel.
the problem: every time the connection status is changing, the conectionStatus
variable changes, which makes a recomposition for the Text composable (this is ok, expected behavior), but it also cause the button to be recomposed, even though nothing changed in the button state.
now, I think the problem is that the connectionState
cause the state for the whole viewModel to be changed, because when I removed the Text composable, and left with only the button composable, it still was recomposed every time the connectionStatus
was changed.
This is my implemntation: ViewModel:
class ConnectableTopAppBarViewModel(
private val connectControllerUseCase: ConnectControllerUseCase = ConnectControllerUseCase()
) :
ViewModel() {
private val _uiState = MutableStateFlow(ConnectableTopAppBarUiState())
val uiState: StateFlow<ConnectableTopAppBarUiState>
get() = _uiState.asStateFlow()
private val _connectionStatus = mutableStateOf(ConnectionStatus.AWAIT_CONNECTION)
val connectionStatus get() = _connectionStatus
private var job = Job()
get() {
if (field.isCancelled) field = Job()
return field
}
init {
viewModelScope.launch {
connectControllerUseCase.getConnectionStatus().collect { newStatus ->
_connectionStatus.value = newStatus
}
}
}
fun cancelConnection(deviceIp: String) {
job.cancel()
connectControllerUseCase.cancelConnection()
}
}
now in my composables I have sometihng like this:
val connectionStatus by viewModel.connectionStatus
...
Text(text = connectionStatus)
...
CustomButton(cancelAction = viewModel::cancelConnection)
...
CustomButton(
cancelAction = (String) -> ()
) {
Button(onClick = { cancelAction("test") })
}
what am I missing here? why CustomButton
is being recomposed every time the connectionStatus
is changed? even though I'm passing method refference.
Upvotes: 2
Views: 817
Reputation: 46
Try:
CustomButton(cancelAction = remember { viewModel::cancelConnection } )
Upvotes: 2