Getting started
How to get up and running with Suas
When using Suas you will build your applications by defining a Store that contains a Reducer. You dispatch Actions to the store that inform Listeners.

Head to Core concepts for an in-depth explanation of Suas components.
Let's get started with using Suas.
Installing Suas in your project
Install Suas by following the installations steps.
Building a counter
When building apps in Suas, we start by defining the state for our counter. In this example, the counter state is a struct that contains the counter value.
struct Counter {
var value: Int
}
data class Counter(val value: Int = 0)
class Counter {
private final int count;
// constructor + getter
}
We then define the actions that affect the state. For the counter, we need increment and decrement actions.
struct IncrementAction: Action {
let incrementValue: Int
}
struct DecrementAction: Action {
let decrementValue: Int
}
data class IncrementAction(val value: Int) : Action<Int>("increment", value)
data class DecrementAction(val value: Int) : Action<Int>("decrement", value)
private static final String INCREMENT_ACTION = "increment";
private static final String DECREMENT_ACTION = "decrement";
private Action getDecrementAction(int value) {
return new Action<>(DECREMENT_ACTION, value);
}
private Action getIncrementAction(int value) {
return new Action<>(INCREMENT_ACTION, value);
}
Now that we have both the State
and the Actions
, we need to specify how actions are going to affect the state. This logic is implemented in the reducer. The counter state reducer looks like the following:
let counterReducer = BlockReducer(state: Counter(value: 0)) { state, action in
// Handle increment action
if let action = action as? IncrementAction {
var newState = state
newState.value += action.incrementValue
return newState
}
// Handle decrement action
if let action = action as? DecrementAction {
var newState = state
newState.value -= action.decrementValue
return newState
}
// Important: If action does not affec the state, return nil
return nil
}
class CounterReducer : Reducer<Counter>() {
override fun reduce(oldState: Counter, action: Action<*>): Counter? {
return when (action) {
// Handle increment action
is IncrementAction -> {
oldState.copy(value = oldState.value + action.value)
}
// Handle decrement action
is DecrementAction -> {
oldState.copy(value = oldState.value - action.value)
}
// Important: If action does not affec the state, return null
else -> null
}
}
// Provide a default value
override fun getEmptyState(): Counter = Counter()
}
private static class CounterReducer extends Reducer<Counter> {
@Nullable
@Override
public Counter reduce(@NonNull Counter oldState, @NonNull Action<?> action) {
switch (action.getActionType()) {
// Handle increment action
case INCREMENT_ACTION: {
int incrementValue = action.getData();
return new Counter(oldState.count + incrementValue);
}
// Handle decrement action
case DECREMENT_ACTION: {
int decrementValue = action.getData();
return new Counter(oldState.count - decrementValue);
}
// Important: If action does not affec the state, return null
default: {
return null;
}
}
}
@NonNull
@Override
public Counter getEmptyState() {
// Provide a default value
return new Counter(0);
}
}
The reducer defines two things:
- The initial state for the store. i.e. the initial
Counter
value. - The reduce function, which receives both the dispatched
Action
and the currentState
. This function decides whatState
to return based on theAction
. If the reducer did not change the state, it should returnnil/null
The Store
is the main component we interact with in the application. The store contains:
- The app's state.
- The reducer, or reducers.
- The middlewares (covered in the advanced section).
We create a store with the following snippet:
let store = Suas.createStore(reducer: counterReducer)
val store = Suas.createStore(CounterReducer()).build()
Store store = Suas.createStore(new CounterReducer()).build();
Now we can dispatch actions to the store and add listeners to it.
Let's start by adding a listener that prints the new value whenever the state changes.
let subscription = store.addListener(type: Counter.self) { state in
print("State changed to \(state.value)")
}
val subscription = store.addListener(Counter::class.java) { _, (value) ->
println("State changed to $value")
}
Subscription subscription = store.addListener(Counter.class, (oldState, newState) ->
System.out.println("State changed to " + newState.count)
);
Notice that we specified the type of the State
. We do this because the state can contain multiple sub-states. We will cover sub-states in the applications with multiple states article.
Finally, we dispatch actions to the store whenever there is an event, such as a user tapping a button.
store.dispatch(action: IncrementAction(incrementValue: 10))
store.dispatch(action: IncrementAction(incrementValue: 1))
store.dispatch(action: DecrementAction(decrementValue: 5))
store.dispatchAction(IncrementAction(10))
store.dispatchAction(IncrementAction(1))
store.dispatchAction(DecrementAction(5))
store.dispatchAction(getIncrementAction(10));
store.dispatchAction(getIncrementAction(1));
store.dispatchAction(getDecrementAction(5));
This would print the following:
State changed to 10
State changed to 11
State changed to 6
When we no longer need the listener, we remove it by calling:
subscription.removeListener()
subscription.removeListener()
subscription.removeListener();
That's it. We implemented our first Suas application. I hope it wasn't that hard
iOS - Linking listener life cycle to an object
We can also tie the
listener
life cycle to an object (Could be a UIView or UIViewController) by using:subscription.linkLifeCycleTo(object: self)
Now that it's linked, we don't have to call
subscription.removeListener()
as it will be removed when the linked object is deallocated.
What's next
Check the list of example applications built with Suas for a runnable version of the Counter example and other examples.
Related Topics
How to install Suas in your project
List of example applications built with Suas
Suas core architecture concepts and elements
Developer experience and tooling
Logging in Suas
Using Suas Monitor
Updated almost 6 years ago