LaunchedEffect starts more that once

83 views Asked by At

I met the problem, which consists in that LaunchedEffect works incorrectly. I want to block in LaunchedEffect start once, when user click to corresponding NavigationBarItem, because block should send only one request to the server. I added immutable parameter Unit to block be non restartable, but tool AppInspection displays that network is using everytime when I click on the navigation button

@Composable
fun PostScreen(postsViewModel: PostsViewModel) {

    val state = postsViewModel.posts.observeAsState()

    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        state.value?.forEach {
            item { Post(it) }
        } ?: item { CircularProgressIndicator() }
    }

    LaunchedEffect(key1 = Unit, block = {
        postsViewModel.getAllPosts()
    })
}
1

There are 1 answers

1
BenjyTec On

LaunchedEffect(Unit) executes a block once when the Composable enters the screen. It fires again whenever you navigate away and then reselect the BottomNavigation item.

Assuming you have the NavHost and BottomNavigation set up with saveState=true and restoreState=true according to the documentation, a solution could be as simple as:

@Composable
fun PostScreen(postsViewModel: PostsViewModel) {

    var initialComposition by rememberSaveable{ mutableStateOf(true) }
    val state = postsViewModel.posts.observeAsState()

    LaunchedEffect(Unit) {
        if (initialComposition) {
            postsViewModel.getAllPosts()
            initialComposition = false
        }
    }

    // ...
}