/InkRedux

My own Redux implementation

Primary LanguageKotlinMIT LicenseMIT

InkRedux

My own Redux implementation. On my prior attempts to make use of the Redux architecture I did not find a java/kotlin library I liked, so this time I made my own.

Dependencies

RxJava3 is used and you need to import it in your project.

Example Usage

Here we have an example Redux Store with some actions and a conversion from some actions to others through middleware. It is the same example used in the companion example app found on this same repository.

import android.annotation.SuppressLint
import com.inlacou.inkredux.*

object GlobalStore: BaseReduxStore<GlobalStore.State, GlobalStore.Actions>(initialState = State(), reducers = listOf(object : ReduxStateReducer<State, Actions> {
	override fun invoke(old: State, action: Actions): State {
		println("invoke $action")
		return when(action) {
			Actions.Increment -> old.copy(value = old.value+1)
			Actions.Decrement -> old.copy(value = old.value-1)
			is Actions.Add -> old.copy(value = old.value+action.value)
			is Actions.Subtract -> old.copy(value = old.value+1+action.value)
		}
	}
}), middleware = listOf(object : ReduxMiddleware<State, Actions>{
	override fun invoke(state: State, action: Actions, dispatch: DispatchAction<Actions>, next: ReduxNextMiddleware<State, Actions>) {
		when (action) {
			is Actions.Add -> if(action.value==1) next(state, Actions.Increment, dispatch) else next(state, action, dispatch)
			is Actions.Subtract -> if(action.value==1) next(state, Actions.Decrement, dispatch) else next(state, action, dispatch)
			else -> { next(state, action, dispatch) }
		}
	}
})) {
	sealed class Actions : ReduxAction {
		object Increment : Actions() { override fun toString(): String { return javaClass.simpleName } }
		object Decrement : Actions() { override fun toString(): String { return javaClass.simpleName } }
		class Add(val value: Int) : Actions() { override fun toString(): String { return "${javaClass.simpleName} | $value" } }
		class Subtract(val value: Int) : Actions() { override fun toString(): String { return "${javaClass.simpleName} | $value" } }
	}
	data class State(
			val value: Int = 0
	): ReduxState

	init { init() }

	@SuppressLint("CheckResult") //GlobalStore will always be up, it is the brain of our app. So we do not need to dispose observables on GlobalStore destroyed, AFAIK
	fun init() {
		//Here we listen to BD changes with Room, for example
	}
}

Read one store value:

tv?.text = GlobalStore.state.value.toString()

Listen to one store value change:

disposables.add(GlobalStore.getSubject().map { it.value }.distinctUntilChanged().toUi().subscribe {
	tv?.text = it.toString()
})

Launch action on store (modify store state):

GlobalStore.applyAction(GlobalStore.Actions.Increment)
//or
GlobalStore.applyAction(GlobalStore.Actions.Add(1))