Readme Index
- Installation
- StoreFlow Core Api
- SideEffects
- Subscriber Aware StoreFlow
- Jetpack Compose Support
- Unit Test Support
Subscriber Aware StoreFlow
Module: com.episode6.redux:subscriber-aware:1.0.1
A SubscriberAwareStoreFlow
acts just like a normal StoreFlow
except that it dispatches a special
action (data class SubscriberStatusChanged(val subscribersActive: Boolean) : Action
) whenever the first subscriber
begins collecting from the StoreFlow and whenever the last subscriber stops collecting from the StoreFlow. If the
StoreFlow is being used to control the state of your UI, then this maps approximately to the UI’s lifecycle.
The SubscriberStatusChanged
action can be handled by your Reducer, Middleware and/or SideEffects.
Example: Lets assume our traffic light StoreFlow is controlled by a server somewhere, instead of the local timing we implemented in the SideEffects Example. We’d likely only want to maintain our connection to the server when there is actually a UI observing our state (otherwise we’d just be wasting cycles).
// assume our server gives us updates via a Flow
interface TrafficServer {
fun lightStateUpdates(): Flow<LightStateUpdates>
}
fun trafficServerListenSideEffect(server: TrafficServer) = SideEffect<TrafficLightState> {
actions.filterIsInstance<SubscriberStatusChanged>().transformLatest { action ->
// we use an if-statement here instead of filtering because we want
// SubscriberStatusChanged(false) to cancel any ongoing transform,
// so instead we just no-op when false
if (action.subscribersActive) {
server.lightStateUpdates().collect { serverUpdate ->
emit(SetGreenLight(serverUpdate.green))
emit(SetYellowLight(serverUpdate.yellow))
emit(SetRedLight(serverUpdate.red))
}
}
}
}
// then we update our creator function to use SubscriberAwareStoreFlow
// and apply our new SideEffect (which is the only one we'll need)
fun trafficLightStore(scope: CoroutineScope, server: TrafficServer) = SubscriberAwareStoreFlow(
scope = scope,
initialState = TrafficLightState(),
reducer = TrafficLightState::reduce,
middlewares = listOf(
SideEffectMiddleware(trafficServerListenSideEffect(server))
)
) // no need to dispatch an initial action because SubscriberStatusChanged
// will be automatically dispatched when the UI starts collecting.