Last active
May 7, 2024 15:47
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}.") | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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