Home > Back-end >  How can I stop a screen from recomposing in Jetpack Compose?
How can I stop a screen from recomposing in Jetpack Compose?

Time:09-02

I have navigation drawer where I have two items:

ModalNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {},
    content = {
        Scaffold(
            topBar = {},
            content = { padding ->
                Box(
                    modifier = Modifier.fillMaxSize().padding(padding)
                ) {
                    when (viewModel.selectedItem) {
                        items[0] -> Home()
                        items[1] -> Products()
                    }
                }
            }
        )
    }
)

Where items is a list that is initialized like this:

val items = listOf(
    Item(Icons.Default.Home, "Home"),
    Item(Icons.Default.List, "Products")
)

And selectedItem is initialized inside the ViewModel like this

var selectedItem by mutableStateOf(items[0])

Where, Home has this content:

fun Home() {
    Column(
        modifier = Modifier.fillMaxSize()
    ) {
        PopularProducts(
            popularProductsContent = { popularProducts ->
                HorizontalContent(
                    products = popularProducts
                )
            }
        )
    }
}

And Products this:

fun Products(
    viewModel: MainViewModel = hiltViewModel(),
) {
    LaunchedEffect(Unit) {
        viewModel.getAllProducts()
    }
    Products { products ->
        Column {
            LazyColumn(
                modifier = Modifier
                    .fillMaxWidth()
                    .wrapContentHeight(),
                contentPadding = PaddingValues(8.dp)
            ) {
                items(products) { product ->
                    ProductCard(
                        product = product
                    )
                }
            }
        }
    }
}

When I launch the app, Home item is loaded. If I navigate away from it, and I get back, everything is alright, the page isn't recomposed. But if I select Products, and I navigate to the product details, for example, when I navigate back, the screen is recomposed (it blinks). Basically another request is made. How can I stop this from happening?

P.S. I use Hilt Navigation.

CodePudding user response:

This is because your LaunchedEffect will be getting called again which is triggering your products to reload.

You just need to cache your products somehow so that reload and reset isn't happening, there are many ways to do that with increasing complexity and architecture but the simplest fix would be just to call viewModel.getAllProducts() in your MainViewModel init instead of having the LaunchedEffect.

  • Related