Skip to content

Instantly share code, notes, and snippets.

@crisu83
Last active January 11, 2022 09:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save crisu83/9f31aac0b71617f2d7bf6786b59fc761 to your computer and use it in GitHub Desktop.
Save crisu83/9f31aac0b71617f2d7bf6786b59fc761 to your computer and use it in GitHub Desktop.
A predictable state container (like Redux) written in Kotlin for use with Android view models.
data class CounterUiState(val counter: Int = 0) : State
sealed class CounterAction : Action {
object Increment : CounterAction()
object Decrement : CounterAction()
data class SetValue(val value: Int) : CounterAction()
}
class CounterViewModel : ViewModel() {
private val store = Store<CounterUiState, CounterAction>(CounterUiState()) { state, action ->
when (action) {
CounterAction.Increment -> state.copy(counter = counter + 1)
CounterAction.Decrement -> state.copy(counter = counter - 1)
CounterAction.SetValue -> state.copy(counter = action.value)
}
}
val uiState = store.stateAsStateFlow()
init {
store.dispatch(CounterAction.Increment) // counter is 1
store.dispatch(CounterAction.SetValue(10)) // counter is 10
store.dispatch(CounterAction.Decrement) // counter is 9
}
}
@Composable
fun Counter(viewModel: CounterViewModel) {
val uiState = viewModel.uiState.collectAsState()
Text("Counter is ${uiState.counter}.")
}
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
interface State
interface Action
typealias Reducer<State, Action> = (State, Action) -> State
class Store<S, A>(
initialState: S,
private val reducer: Reducer<S, A>,
) where S : State, A : Action {
private val state = MutableStateFlow(initialState)
val currentState get() = state.value
fun dispatch(action: A) {
state.update { reducer(it, action) }
}
fun stateAsStateFlow(): StateFlow<S> {
return state.asStateFlow()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment