MVICore
MVICore copied to clipboard
Private state representation for feature
I have a NavFeature which handles routes. NavWish(path: String) goes in and NavState(module: String, args : ...) goes out. All my code depends on Store<NavWish, NavState>. Now I want to use a stack with NavStates, but I don't want the rest of my code to know that I'm using a Stack.
What is the best way to expose a Store-interface without the stack, but use the stack interrnally?
Hi @tieskedh Currently, feature does not support private states, but you can hide it using binder.
// state in feature
data class State(
val stack: List<String>
)
// somewhere outside
binder.bind(feature to navigator using StateToNavigator)
object StateToNavigator : (State) -> NavState {
override fun invoke(state: State): NavState = NavState(state.stack.last())
}
But in that case, the class passed around doesn't implement Store anymore... At this moment I'm using the following code:
class PublicNavigationFeature : Store<NavigationWish, NavigationState>{
private val subject = BehaviorSubject.create<NavigationStackState>()
val navigationStackFeature = NavigationStackFeature().apply {
subscribe(subject)
}.wrapWithMiddleware()
override val state: NavigationState get() = subject.value!!.navigationState.last()
override fun accept(wish: NavigationWish) = navigationStackFeature.accept(wish)
override fun subscribe(observer: Observer<in NavigationState>) {
subject.map {
it.navigationState.lastOrNull() ?: NavigationState("close", "close")
}.subscribe(observer)
}
}
If you subscribe to state update directly, it is possible to use abstraction similar to yours (although it is better to call it PublicNavigationStore
as it is not a feature anymore).
We encourage using Binder nonetheless, as it will take care of lifecycle management, so nothing will be leaked. You can pass NavigationStackFeature
around (it implements store) and use transformer to access required fields. As the state is not mutable anyway, you won't be able to update it from outside, so the stack data will be consistent.