TCA 1.7以前で抱えていた画面遷移の悩み
TCAでの画面遷移を実装する際、↓のように遷移先を定義するためのReducerを実装することがあるかと思います。
@Reducer
struct Path {
@ObservableState
enum State: Equatable {
case login(LoginReducer.State)
case home(HomeReducer.State)
}
enum Action {
case login(LoginReducer.Action)
case home(HomeReducer.Action)
}
var body: some ReducerOf<Self> {
Scope(state: \.login, action: \.login) {
LoginReducer()
}
Scope(state: \.home, action: \.home) {
HomeReducer()
}
}
}
このPath
というReducer、1つ画面遷移先を増やすためだけに
- State
- Action
- Scope
と3箇所にコードを追加する必要があり、
さらに遷移先が多くなってくると「それぞれ順番合わせた方が読みやすいかな」といったように可読性のための作業も増えてしまい、個人的に結構ストレスを抱えていました。
これがTCA 1.8で強化されたマクロによって、大幅にコード量を削減できるようになっていたので共有します。
Reducerマクロで解決
僕はExampleを読み漁っていて、「なんだこれ!めっちゃいいじゃん!」ってなった(該当箇所)のですが、ちゃんと Migration Guide に記載がありました。
https://pointfreeco.github.io/swift-composable-architecture/main/documentation/composablearchitecture/migratingto1.8#Destination-and-path-reducers
元々の Path
が
@Reducer
struct Path {
@ObservableState
enum State: Equatable {
case login(LoginReducer.State)
case home(HomeReducer.State)
}
enum Action {
case login(LoginReducer.Action)
case home(HomeReducer.Action)
}
var body: some ReducerOf<Self> {
Scope(state: \.login, action: \.login) {
LoginReducer()
}
Scope(state: \.home, action: \.home) {
HomeReducer()
}
}
}
こうなります。スッキリ。
@Reducer(state: .equatable)
enum Path {
case login(LoginReducer)
case home(HomeReducer)
}
マクロを展開してみると、しっかりと元のReducerと(ほぼ)同じコードが展開されていることが分かります。
小ネタですが、同じ悩みを抱えられている方の助けになれば幸いです!