komposable-architecture icon indicating copy to clipboard operation
komposable-architecture copied to clipboard

Make the `Store` expose a `StateFlow` instead of a `Flow`

Open thuutin opened this issue 1 year ago • 2 comments

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.

thuutin avatar Apr 11 '23 13:04 thuutin

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)
        }
    )

sveltema avatar Apr 11 '23 17:04 sveltema

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 🤔

heytherewill avatar Apr 17 '23 13:04 heytherewill