코드 내에 있는 주석은 코드를 작성해보며 매우 주관적으로 적은 내용으로, 참고하면 파일 구조 파악에 도움이 된다. 유튜브에 올라와 있는 참고 영상에서 사용하는 용어 및 주석을 참고하였으며, deprecated된 부분을 공식 문서를 참고하여 재구성하였다.
//
// CounterView.swift
// TCA_Simple_tutorial
//
// Created by Tony on 2022/10/27.
//
import SwiftUI
import ComposableArchitecture
// Feature 자체가 Reducer Protocol을 준수하며, 내부에서 실제 reduce function을 통해 실제 논리와 동작을 처리함
struct CounterFeature: ReducerProtocol {
// 도메인(어떤 걸 만들 때 거기에 대한 데이터) + 상태
struct CounterState: Equatable {
var count = 0
}
// 도메인 + 액션
enum CounterAction: Equatable {
case addCount
case subtractCount
}
// 리듀서: 액션과 상태를 연결시켜주는 역할
func reduce(into state: inout CounterState, action: CounterAction) -> EffectTask<CounterAction> { // 외부에서 일어난 일을 다시 store로 가져와서 상태를 변경 시킬 때 Effect 씀
// 들어온 액션에 따라 상태를 변경
switch action {
case .addCount:
state.count += 1
return .none
case .subtractCount:
state.count -= 1
return .none
}
}
}
struct CounterView: View {
// store: Feature(Reducer Protocol을 준수하는)의 스토어임, 상태, 액션을 가지고 있음 - 커맨드 센터 역할
let store: StoreOf<CounterFeature>
var body: some View {
WithViewStore(self.store) { viewStore in
VStack {
Text("count: \(viewStore.state.count)")
.padding()
HStack {
Button("더하기", action: {viewStore.send(.addCount)}) // send: 커맨드센터인 store에 액션을 주문함
Button("빼기", action: {viewStore.send(.subtractCount)})
}
}
}
}
}
//struct CounterView_Previews: PreviewProvider {
// static var previews: some View {
// CounterView()
// }
//}
//
// TCA_Simple_tutorialApp.swift
// TCA_Simple_tutorial
//
// Created by Tony on 2022/10/27.
//
import SwiftUI
import ComposableArchitecture
@main
struct TCA_Simple_tutorialApp: App {
var body: some Scene {
WindowGroup {
CounterView(
store: Store(
initialState: CounterFeature.CounterState(),
reducer: CounterFeature() // Feature 자체가 Reducer Protocol을 준수하기 때문에 reducer parameter에 그대로 CounterFeature()를 넣음
)
)
}
}
}