LoginSignup
2
1

[TCA] TCA 1.8で強化されたマクロで画面遷移処理の見通しを大幅に改善する

Last updated at Posted at 2024-03-28

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と(ほぼ)同じコードが展開されていることが分かります。

image.png

小ネタですが、同じ悩みを抱えられている方の助けになれば幸いです!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1