tokopedia / RxComposableArchitecture

RxComposableArchitecture is a forked of Composable Architecture with adjustment to make it work with UIKit.
Apache License 2.0
31 stars 5 forks source link

Add new store send and scope mechanism #25

Closed jeffersonsetiawan closed 2 years ago

jeffersonsetiawan commented 2 years ago

https://github.com/pointfreeco/swift-composable-architecture/pull/616 https://github.com/pointfreeco/swift-composable-architecture/pull/619

new scope https://github.com/pointfreeco/swift-composable-architecture/pull/616

⚠️ Breaking behavior change ⚠️

switch action {
    case .didTapButton:
        state.toastMessage = "This is a toast"
        return Effect(value: .resetToast) // ❌ This is forbidden in the newScope ❌
    case .resetToast:
        state.toastMessage = nil
        return .none
}

When subscribing:

store.subscribe(\.toastMessage)
    .filterNil()
    .subscribe(onNext: {
        Toast.shared.display($0)
    })

It will not print anything, because the Store will skip emitting the "This is a toast", as it will directly changed to nil again.

This behavior is expected to increase the store scope/send performance.

To overcome this issue, please do this instead:

  1. Reset in the UI
    
    switch action {
    case .didTapButton:
        state.toastMessage = "This is a toast"
        return .none
    case .resetToast:
        state.toastMessage = nil
        return .none
    }

// UI store.subscribe(.toastMessage) .filterNil() .subscribe(onNext: { Toast.shared.display($0) store.send(.resetToast) // ✅ })

2. Move to Environment
```swift
switch action {
    case .didTapButton:
        return env.showToast("This is a toast").fireAndForget() // ✅
}
  1. Use NeverEqual Property Wrapper
    
    struct State {
    @NeverEqual var toastMessage: String? // ✅
    }

switch action { case .didTapButton: state.toastMessage = "This is a toast" return .none }

// UI store.subscribe(.toastMessage) .filterNil() .subscribe(onNext: { Toast.shared.display($0) })