komposable-architecture
komposable-architecture copied to clipboard
Make the `Store` expose a `StateFlow` instead of a `Flow`
Description
Make the Store
expose a StateFlow
instead of a Flow
so it's easier to use in Compose. With StateFlow
we can just use collectAsState()
without providing an initial value and reducing recompositions.
Pretty sure that to change store state to val state: StateFlow<State>
, the signature of fun optionalView
would have to change to something like:
fun <ViewState : Any, ViewAction : Any> optionalView(
mapToLocalState: (State) -> ViewState?,
mapToGlobalAction: (ViewAction) -> Action?
): Store<ViewState?, ViewAction>
or:
fun <ViewState : Any, ViewAction : Any> optionalView(
initialState: ViewState,
mapToLocalState: (State) -> ViewState?,
mapToGlobalAction: (ViewAction) -> Action?
): Store<ViewState, ViewAction>
When the mapToLocalState
lambda returns an optional, there is no good way (?) to provide a non-optional initial value for a stateIn()
function. For example from MutableStateFlowStore
the required mapToLocalState(state.value)!!
would cause crashes when the mapToLocalState
lambda returns null.
For example:
override fun <ViewState : Any, ViewAction : Any> optionalView(
mapToLocalState: (State) -> ViewState?,
mapToGlobalAction: (ViewAction) -> Action?
): Store<ViewState, ViewAction> = MutableStateFlowStore(
state = state.mapNotNull { mapToLocalState(it) }
.stateIn(storeScope, SharingStarted.WhileSubscribed(), mapToLocalState(state.value)!!),
sendFn = { actions ->
val globalActions = actions.mapNotNull(mapToGlobalAction)
sendFn(globalActions)
}
)
What sveltema said above is the reason we didn't implement this change while I was at toggl. We couldn't agree on what the API for optionalView should look like 🤔