[Swift] TCAでSideMenuViewを実装してみた  

## はじめに
こんにちは!
アプリ開発が好きで、Swiftの勉強をしている大学生です。
温かい目で見ていただけると幸いです。

## やりたいこと
インターン先でTCAを使ったプロジェクトに関わっているため、TCAの勉強をしています。
そのため、以前に投稿した下記の`SideMenuView`をTCAで実装してみました。

https://qiita.com/kanta_Swift/items/e2298c813974ced24741

## 実装
まずは`Reducer`の実装です。
```swift
public struct HogeReducer: Reducer {
    // MARK: - State
    public struct State: Equatable {
        var offset: CGFloat = 0
        var screenSizeWidth: CGFloat = 0
        var sideBarWidth: CGFloat = 0
        var showSideBar: Bool = false
    }
    
    // MARK: - Action
    public enum Action: Equatable {
        case viewAppeared(CGFloat)
        case changeShowSideBar(CGFloat)
        case sideMenuButtonTapped
        case rectangleTapped
    }
    
    // MARK: - Dependencies
    public init() {}
    
    // MARK: - Reducer
    public func reduce(into state: inout State, action: Action) -> Effect<Action> {
        switch action {
        case let .changeShowSideBar(size):
            if state.showSideBar && state.offset == 0 {
                state.offset = size - 90
            }
            
            if !state.showSideBar && state.offset == size - 90 {
                state.offset = 0
            }
            return .none
            
        case let .viewAppeared(size):
            state.screenSizeWidth = size
            state.sideBarWidth = size - 90
            return .none
            
        case .sideMenuButtonTapped:
            state.showSideBar.toggle()
            return .none
            
        case .rectangleTapped:
            state.showSideBar.toggle()
            return .none
        }
    }
}
```
続いてViewの実装です。

```swift
public struct HogeView: View {
    @ObservedObject private var viewStore: ViewStoreOf<HogeReducer>
    let store: StoreOf<HogeReducer>

    public init(store: StoreOf<HogeReducer>) {
        self.store = store
        self.viewStore = ViewStore(store, observe: { $0 })
    }

    public var body: some View {
        HStack(spacing: 0) {
            
            SideMenuView()
            
            VStack {
                Button("SideMenuView") {
                    viewStore.send(.sideMenuButtonTapped)
                }
            }
            .frame(width: viewStore.screenSizeWidth)
            .frame(maxHeight: .infinity)
            .overlay {
                Rectangle()
                    .fill(
                        Color.primary
                            .opacity(Double((viewStore.offset / (viewStore.screenSizeWidth - 90) ) / 5))
                    )
                    .ignoresSafeArea(.container, edges: .vertical)
                    .onTapGesture {
                        viewStore.send(.rectangleTapped)
                    }
            }
        }
        .frame(width: viewStore.screenSizeWidth + viewStore.sideBarWidth)
        .offset(x: -viewStore.sideBarWidth / 2)
        .offset(x: viewStore.offset > 0 ? viewStore.offset : 0)
        .onChange(of: viewStore.showSideBar) { _ in
            viewStore.send(.changeShowSideBar(getScreenRect()), animation: .default)
        }
        .onAppear {
            viewStore.send(.viewAppeared(getScreenRect()))
        }
    }
}

```
これで実装できました！
TCA慣れるまでかなり時間かかりそうです...

## 終わりに
誰かの役に立つことができていれば幸いです。
アウトプットを頑張ろうと思っているので温かい目で見ていただけると嬉しいです。