Daniele B
03/15/2021, 1:37 PMmodel.loadDetailData(it)
call to the composable("detail/{item}")
, but I can’t find a Compose API to do that. If I include the call inside the composable
block, above DetailView
, such call gets executed at each recomposition, creating a never-ending loop.
@Composable
fun Navigation(model: KMPViewModel) {
val appState by model.stateFlow.collectAsState()
val navController = rememberNavController()
NavHost(navController, startDestination = "master") {
composable("master") {
MasterView(masterState = appState.masterState,
onListItemClick = {
navController.navigate("detail/$it")
model.loadDetailData(it)
}
)
}
composable("detail/{item}") {
DetailView(detailState = appState.detailState)
}
}
}
what is the right way to make it work with deep linking?Ian Lake
03/15/2021, 1:54 PMDaniele B
03/15/2021, 1:57 PMonAppear
function on the DetailView. But on Jetpack Compose I don’t know how to trigger a function when a Composable first appears (and not on subsequent recompositions).Bryan Herbst
03/15/2021, 2:00 PMDaniele B
03/15/2021, 2:05 PMDaniele B
03/15/2021, 5:58 PMNavHost(navController, startDestination = "master") {
composable("master") {
MasterView(masterState = appState.masterState,
onListItemClick = { navController.navigate("detail/$it") }
)
}
composable("detail/{item}") { backStackEntry ->
val item = backStackEntry.arguments?.getString("item")!!
LaunchedEffect(item) { model.loadDetailData(item) }
DetailView(detailState = appState.detailState)
}
}
it works! Thanks again!Daniele B
03/15/2021, 6:31 PMLaunchedEffect
is triggering an extra recomposition.
model.loadDetailData()
on its own is causing the state to change twice (correctly, as one is for setting appState.detailState.isLoading
to true before fetching the data, and one is to set the appState.detailState.detailData
object after fetching it from the repository.
• If I call model.loadDetailData()
from the master onListItemClick, as in the first example, the recomposition happens 2 times.
• If I call model.loadDetailData()
from the detail LaunchedEffect the recomposition happens 3 times.Ian Lake
03/15/2021, 6:37 PMLaunchedEffect
runs the frame after first composition, so that sounds expected. You could certainly set your default appState to your loading stateDaniele B
03/15/2021, 6:46 PMcomposable
and executes it just before the first composition, similar to the onAppear
function in SwiftUI.Ian Lake
03/15/2021, 6:49 PMappState
- you could certainly have each destination have its own state that is automatically cleared when that destination is popped off the back stackDaniele B
03/15/2021, 6:56 PMIan Lake
03/15/2021, 7:03 PMDaniele B
03/15/2021, 10:57 PMIan Lake
03/15/2021, 11:00 PMIan Lake
03/15/2021, 11:01 PMLaunchedEffect
, and any other Compose API should be usedDaniele B
03/16/2021, 12:44 AMNavigation Composable
(excluding the chance to hoist the state outside the scope), doesn’t seem right to me. There are screens, with different navigation addresses, that should be able to share a ViewModel.
The current solution of using LaunchedEffect
and triggering an extra recomposition is definitely not ideal.
I think for the moment, I will still run the loadDetailData()
function from the master list item onClick, as I don’t have the need to implement deep linking. But I hope that this issue will be taken into consideration for the 1.0 version. If it helps, I could file an issue about that.Ian Lake
03/16/2021, 1:44 AMDaniele B
03/16/2021, 10:28 AM