resultOf
Observes the result of type T returned by a child screen via backWithResult.
The result is consumed exactly once: the returned State transitions from null to the received value and stays at that value until the composable leaves the composition.
Implementation notes:
Uses KClass.simpleName as the map key — available on all KMP targets (Android, iOS, Desktop, JS, WASM). KClass.qualifiedName is not supported in Kotlin/JS.
The results map is a androidx.compose.runtime.snapshots.SnapshotStateMap, so reading it inside derivedStateOf creates a reactive dependency — recomposition triggers automatically the moment backWithResult puts a matching entry.
SideEffect runs synchronously after every successful recomposition. When a pending value is observed it is removed from results and committed to the stable local State in the same frame — eliminating the one-frame null window that a LaunchedEffect would introduce.
Prefer the inline reified overload resultOf when the type is known at the call site:
val result by navController.resultOf<ProfileScreen.Result>()Parameters
The KClass of the expected result type.
Inline reified convenience overload of resultOf.
Observes the result of type T posted by a child screen via backWithResult. The result is consumed exactly once — see resultOf for full semantics.
Pattern for io.github.alimsrepo.navease.runtime.screen.ActivityScreen
Define the result as a nested data class inside the child screen, then observe it in the parent screen using this function:
// ── Child screen — posts a result before popping ─────────────────────────
class ProfileScreen : ActivityScreen<AppScreens.Profile>() {
data class Result(val selectedUserId: Int)
@Composable
override fun Content(navKey: AppScreens.Profile, navController: NavController) {
Button(onClick = {
navController.backWithResult(Result(selectedUserId = 42))
}) { Text("Select") }
}
}
// ── Parent screen — observes the result ──────────────────────────────────
class HomeScreen : ActivityScreen<AppScreens.Home>() {
@Composable
override fun Content(navKey: AppScreens.Home, navController: NavController) {
val result by navController.resultOf<ProfileScreen.Result>()
result?.let { Text("Selected user #${it.selectedUserId}") }
Button(onClick = { navController.navigate(AppScreens.Profile) }) {
Text("Open Profile")
}
}
}Type Parameters
The expected result type. Typically a nested data class inside the child screen.