Micro-framework for Redux implemented in Kotlin
dependencies {
repositories {
jcenter()
}
}
implementation("com.mercari.rxredux:rxredux:<latest-version>")
This framework is composed of several types/abstractions inspired by Redux that help to implement the reactive behavior of application components. It is based on RxJava for reactivity and works well with RemoteDataK.
State represents the model or state of your component or UI. A State is recommended to be immutable, however it can be allowed to be mutable.
This can typically be implemented by a data class
For example:
data class CounterState(
val counter: Int
) : State
An Action represents the desired modifications on a State, for example
class Increment : Action
class Decrement : Action
Although not required, it is recommended to model Actions as class hierarchy with a sealed class.
sealed class CounterAction : Action
class Increment : CounterAction()
class Decrement : CounterAction()
An Action can contain parameters that make them more useful depending on the desired behaviour. For example:
class Increment(val by: Int) : CounterAction
Actions are to be dispatched through the Store's dispatch method to perform State mutations.
For example:
store.dispatch(Increment(2))
A Reducer is where the State is mutated or modified, depending on which Action is applied. It is basically a map of the desired modifications and their effects.
For example:
class CounterReducer: Reducer<CounterState, CounterAction> {
override fun reduce(currentState: CounterState, action: CounterAction) : CounterState =
when(action) {
is Increment -> CounterState(counter: currenState.counter + action.by)
is Decrement -> CounterState(counter: currenState.counter - action.by)
}
}
Middleware allows for a variety of behaviours that are not directly related to the component's State. This is useful for the implementation of so called cross-cutting concerns such as Logging, by hooking into the sequence of Action events.
Middleware can run before reducing the state or after depending on the need, this can be achieved by overriding the provided methods.
The Store "stores" the State, and exposes it for observation as an Observable. It also connects all the other abstractions together.
To create a Store, simply instantiate it with an initial State and its related Reducer:
val counterStore = Store(initialState, reducer)
Several middleware can also be added to the Store through the Store's addMiddleware method.
Examples of usage can be seen in the tests