Skip to content

Your first and simplest feature

Reducer

Your simplest Feature would be one which only uses a Reducer to create and emit new states based on the latest one and an incoming effect.

The Reducer is basically a function defining just that:

typealias Reducer<State, Effect> = (State, Effect) -> State

The name Effect is used here in the more generic context.

Note

Later there will be a distinction between Wishes and Effects, but for now, they are one and the same in this simplest example.

Important

Invocations of the reducer must always happen on the same thread to ensure that new Effects are always applied to the latest State and we are not losing modifications.

If two threads were to read Staten, then apply some Effect over it, one would derive Staten+1', while the other would derive Staten+1'' from it, and depending on the order of execution, one or the other would be lost. By enforcing the single-thread policy, all Effects are always applied to the latest state.

Exercise #1

Task

  • Let's store a counter in our state
  • Let's make it possible to increment this counter by a Wish

Solution using ReducerFeature

Meet the simplest Feature, the ReducerFeature:

class Feature1 : ReducerFeature<Wish, State, Nothing>(
    initialState = State(),
    reducer = ReducerImpl()
) {

    data class State(
        val counter: Int = 0
    )

    sealed class Wish {
        object IncrementCounter : Wish()
    }

    class ReducerImpl : Reducer<State, Wish> {
        override fun invoke(state: State, wish: Wish): State = when (wish) {
            IncrementCounter -> state.copy(
                counter = state.counter + 1
            )
        }
    }
}

Under the hood, ReducerFeature is a subclass of BaseFeature giving you a subset of all the possibilities there.

It will also wire everything up for you (reacting to a Wish, calling your Reducer, emitting your next State).

When should you use ReducerFeature

  • There are no async jobs in your Feature
  • There's no extra business logic. Whatever comes in as a Wish, always modifies the State without a question, and we just want to keep track of it.