I am trying to show a list of Orders in a list using LazyColumn. Here is the code:
@Composable
private fun MyOrders(
orders: List<Order>?,
onClick: (String, OrderStatus) -> Unit
) {
orders?.let {
LazyColumn {
items(
items = it,
key = { it.id }
) {
OrderDetails(it, onClick)
}
}
}
}
@Composable
private fun OrderDetails(
order: Order,
onClick: (String, OrderStatus) -> Unit
) {
println("Composing Order Item")
// Item Code Here
}
Here is the way, I call the composable:
orderVm.fetchOrders()
val state by orderVm.state.collectAsState(OrderState.Empty)
if (state.orders.isNotEmpty()) {
MyOrders(state.orders) {
// Handle status change click listener
}
}
I fetch all my orders and show in the LazyColumn. However, when a single order is updated, the entire LazyColumn gets rrecomposed. Here is my ViewModel looks like:
class OrderViewModel(
fetchrderUseCase: FetechOrdersUseCase,
updateStatusUseCase: UpdateorderUseCase
) {
val state = MutableStateFlow(OrderState.Empty)
fun fetchOrders() {
fetchrderUseCase().collect {
state.value = state.value.copy(orders = it.data)
}
}
fun updateStatus(newStatus: OrderStatus) {
updateStatusUseCase(newStatus).collect {
val oldOrders = status.value.orders
status.value = status.value.copy(orders = finalizeOrders(oldOrders))
}
}
}
NOTE: The finalizeOrders()
does some list manipulation based on orderId to update one order with the updated one.
This is how my state looks like:
data class OrderState(
val orders: List<Order> = listOf(),
val isLoading: Boolean = false,
val error: String = ""
) {
companion object {
val Empty = FetchOrdersState()
}
}
If I have 10 orders in my DB and I update one's status (let's say 5th item), then OrderDetails
gets called for 20 times. Not sure why. Caan I optimize it to make sure only the 5th indexed item will be recomposed and the OrderDetals
gets called only with the new order.