:thinking_face: I'm going to use `CompositionLocal...
# compose-android
y
🤔 I'm going to use
CompositionLocal
to provide a
NavController
across my composables, and it works well for basic navigation. But I’m curious about real-world experience and advanced use cases: • Is using
CompositionLocal
for
NavController
still considered idiomatic in larger Compose apps?
đźš« 3
val LocalNavController = compositionLocalOf<NavHostController> {
error("No NavController provided")
}
@Composable
fun MyApp() {
val navController = rememberNavController()
CompositionLocalProvider(LocalNavController provides navController) {
Scaffold {
NavHost(
navController = navController,
startDestination = "home"
) {
composable("home") { HomeScreen() }
composable("details") { DetailScreen() }
}
}
}
}
@Composable
fun HomeScreen() {
val navController = LocalNavController.current
Button(onClick = { navController.navigate("details") }) {
Text("Go to Details")
}
}
This is our idea but I don't know is this good idea or not, I want to discuss that
c
This is in ways worse or on par with having a global static something and just throwing messages to it, and hoping someone on the other side will understand it. (remember EventBus) Some people pass down navigation callbacks to the Screen Composables from the NavHost side, and let the screens call specific stuff, like navigateBack, navigateToDetails, so it is the NavHost side’s responsibility to define how these work. Our approach is more like have a fixed set of “Commands” or “Routes” whatever you want to call them, and pass these via a Dependency Injected NavigationManager from ViewModels to the place where the NavHost registers the actual Screens. This decouples navigation events from the underlying implementation (we used to work the same system for FragmentManager based navigation)
what you want to avoid is having to manually verify that “details” exists on both sides. If you start adding naigation parameters and potentially 10s or 100s of screens that is where everything will go out of hands
Whenever you want to add something to CompositionLocal you should ask “is there a way to do this using Dependency Injection instead?” Apart from strictly UI related stuff like colors and text styles and whatnot, the answer will usually be yes
y
I used this kind of navigation in my old project, we used the dependency injected Navigator class too, in this class we have one Channel to receive events from view models. But now, I just want to know what happens if we use Composition Local to pass a navigation controller. I guessed possible performance issues and want to clarify my doubts with the experienced community. Thanks for your answer @Csaba Szugyiczki!
👍 1
c
There is a short section about this topic in the docs: https://developer.android.com/develop/ui/compose/compositionlocal#deciding
👍 1
I do not think it would add performance penalties. It would just make the code messier, harder to reason about and harder to test in isolation
y
Yes, I read these docs. Now I have found the reasons why I shouldn't use Composition Local in this case. Thanks again @Csaba Szugyiczki!.
👍 1