1

i am using ReSwift in my project to get a nice and clean redux architecture.

As i am not interested in the whole state i just subscribe to two substates for my viewcontroller:

extension ViewController: StoreSubscriber {

    override func viewWillAppear(_ animated: Bool) {
        store.subscribe(self) {
            $0.select {
                ($0.subStateA, $0.subStateB)
            }
        }
    }

    override func viewWillDisappear(_ animated: Bool) {
        store.unsubscribe(self)
    }

    func newState(state: (subStateA: SubStateA, subStateB: SubStateB)) {
        print("test")
    }

}

What happens:

My newState method is called every time any update happens to the store.

For example if i update subStateC it still triggers

func newState(state: (subStateA: SubStateA, subStateB: SubStateB)) {}

Can anybody explain why this happens?

Thanks and Greetings!

Creative crypter
  • 1,348
  • 6
  • 30
  • 67

2 Answers2

1

You can use skipRepeats after select invocation.

This problem is when you need only update state if substate was changed, using skipRepeats you can put a check if this is true you will skip the update, look this code to try to understand.

Example Code

This is a simple code about a state with navigation state and we want update state when navigation state change.

    store.subscribe(self) { (subscriber:Subscription<State>) -> Subscription<RoutingState> in
        subscriber.select({ (state:State) -> RoutingState in
            return state.routing;
        }).skipRepeats({ (oldRoutingState, newRoutingState) -> Bool in
            return oldRoutingState.navigationState == newRoutingState.navigationState
        })
    }

This code will prevent call newState if nothing change in your filter.

I hope was helpful

ViTUu
  • 1,204
  • 11
  • 21
0

Just do not subscribe whole ViewController or your ViewModel to states. You can make subclasses (for example DataProvider) - subscribers for each state you need.

ViewController: UIViewController {
    let dataProviderA = DataProviderA()
    let dataProviderB = DataProviderB()

    func viewDidLoad() {
        super.viewDidLoad()
        store.subscribe(self.dataProviderA) { $0.select { state in state.subStateA }. skipRepeats() }
        store.subscribe(self.dataProviderB) { $0.select { state in state.subStateB }. skipRepeats() }
    }
}

and your dataProviders must be StoreSubscribers of course:

class DataProviderA: StoreSubsciber<SubStateA> {
    func newState(state: SubStateA) {
         handle(state)
    }
 }

class DataProviderB: StoreSubsciber<SubStateB> {
    func newState(state: SubStateB) {
         handle(state)
    }
 }

I trust this is right approach - each object handle single state. Cheers!

zzheads
  • 1,368
  • 5
  • 28
  • 57