Jetpack Compose NavHost recomposition composable multiple times
D

2

26

I found out that the composable screens are getting recomposition multiple times during navigation from Navhost compose the following example shows how I'm integrating the navigation with logs to identify how many time the function is getting called,

internal sealed class Screen(val route: String) {
  object Splash : Screen("splash")
  object Login : Screen("login")
  object Credentials : Screen("credentials/{type}") {
    fun createRoute(type: String) = "credentials/$type"
  }
}

@Composable
fun HostNavGraph(
  modifier: Modifier = Modifier,
  startDestination: String = Splash.route,
) {
  val navController = rememberNavController()
  val vm: CredentialsViewModel = getViewModel()
  NavHost(navController = navController, startDestination = startDestination, modifier = modifier) {
    composable(route = Splash.route) {
      Log.e("composable", " Splash")
      SplashScreen(openLogin = {
        navController.navigate(Login.route)
      }, openRegistration = { type ->
        navController.navigate(Credentials.createRoute(type))
      })
    }
    composable(route = Login.route) {
      Log.e("composable", " Login")
      val context = LocalContext.current
      LoginScreen(openRegistration = { type ->
        navController.navigate(Credentials.createRoute(type))
        {
          popUpTo(Splash.route) { inclusive = false }
        }

      }, openWebView = {
        openWebView(context, it)
      })
    }
    //..
  }
}

And after running the code this is how the navigation behaves after Opening Splash once then Opening LoginScreen once

15:05:14 E/composable:  Splash 
15:05:14 E/composable:  Splash 
15:05:25 E/composable:  Splash 
15:05:25 E/composable:  Login  
15:05:26 E/composable:  Splash 
15:05:26 E/composable:  Login  
15:05:26 E/composable:  Login  

I also tried some Google examples with Navigation compose, it behaves the same way, so is this an intended behavior?? or is it a bug
navigation_version = '2.4.0-alpha08'

Donatus answered 14/9, 2021 at 11:7 Comment(4)
any solutions about this?Tittle
How did you solve this?Mcculley
Plz guide me how to solve this issue.Lushy
It was marked won't fix at issuetracker.google.com/issues/225987040Butanol
A
9

I'm not sure but I think the NavHost has a built-in animation whenever there is a transition. and with the animation, the recomposition could happen frequently as often as every frame.

A composable function might be run quite frequently, as often as every frame of an animation.

**Android compose

Austrasia answered 26/9, 2021 at 13:56 Comment(0)
G
1

It's not a bug. NavHost is a composable, So naturally it can be composed and recomposed several times! If you want to do a one-time action in a composable lifecycle, use LaunchedEffect.

composable(route = Login.route) {
  LaunchedEffect(key){ // relaunched every time its parameter changes
      //It's a good idea to pass the user ID as an argument and use it as the key
      Log.e("composable", " Login")
      }
  ...
  })

Log.e() is a side effect because it affects the state outside the scope of the composable function. A side effect is an operation that does not affect the UI directly, such as logging.

Gourmont answered 6/11, 2023 at 13:8 Comment(1)
this is one of the recommended suggestions found here. youtube.com/watch?v=Kp-aiSU8qCUUltramodern

© 2022 - 2024 — McMap. All rights reserved.