Changes

Changes<State> wraps primitive value inside and previous one. This data structure enables to get differences between now one and previous one. It helps us to prevent duplicated operation with the same value from the state.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/5e065263-70b3-4d41-b68f-330ea7eddbb4/Untitled.png

Changes structure

How we update UI with the state uniquely in UIKit

In subscribing the state and binding UI, it’s most important to reduce the meaningless time to update UI. What things are the meaningless? that is the update UI operations which contains no updates. Basically, we can prevent this with like followings:

func updateUI(newState: State) {
  if self.label.text != newState.name {
    self.label.text = newState.name
  }
}

Although, this approach make the code a little bit complicated by increasing the code that updates UI. Especially, same words come up a lot.

Changes simplify the code

Actually, state property of Store returns Changes<State> implicitly. From the power of dynamicMemberLookup, we can use the property of the State with we don’t know that is actually Changes object.

How to know there is differences is using ifChanged.

let store: MyStore
let state: Changes<MyState> = store.state

state.ifChanged(\\.name) { name in
  // called when `name` changed only
}

Patterns of ifChanged

ifChanged has a bunch of overloads. Let’s take a look of patterns.

state.ifChanged(\\.aaa, \\.bbb) { aaa, bbb in
  // Executes every two properties change.
}
state.ifChanged({ "Mr." + $0.name }) { composedName in

}
state.ifChanged({ "Mr." + $0.name }, { $0 == $1 }) { aaa, bbb in

}