@Reducer
struct Feature {
enum Action {
case decrementButtonTapped
case incrementButtonTapped
case numberFactButtonTapped
case factAlertDismissed
case numberFactResponse(String)
}
}
Body 정의
실제 로직 수행, Effect를 실행하고 반환 부분을 구현해야 한다. 그리고 현재 상태를 다음 상태로 묘사하는데에 사용된다.
var body: some Reducer<State, Action> {
Reduce { state, action in
switch action {
case .factAlertDismissed:
state.numberFactAlert = nil
return .none
case .decrementButtonTapped:
state.count -= 1
return .none
case .incrementButtonTapped:
state.count += 1
return .none
case .numberFactButtonTapped:
return .run { [count = state.count] send in
let (data, _) = try await URLSession.shared.data(
from: URL(string: "http://numbersapi.com/\(count)/trivia")!
)
await send(
.numberFactResponse(String(decoding: data, as: UTF8.self))
)
}
case let .numberFactResponse(fact):
state.numberFactAlert = fact
return .none
}
}
}
View 정의
Feature를 정의했다면 View를 정의할 차례이다. View에서는 상태를 관찰할 수 있는 Store 객체를 들고 있어야 한다.
Store는 Runtime이라고 했다. State, Action, Reducer를 가지고 있는 친구인데 Store를 실제로 관찰하거나 Store에 액션을 전송하기 위해서는 ViewStore로 한 번 감싸져야 한다. ViewStore가 ObservableObject이기 때문이다. Store를 ViewStore로 변환해주는 역할을 하는 것이 WithViewStore 구조체이다.
State 정의
기능의 상태 타입을 정의해야 한다. (e.g. 알림 문자열, 카운트 등의 변수)
Action 정의
Action은 명백한 동작과 다소 명확하지 않은 동작으로 구분할 수 있다:
Body 정의
실제 로직 수행, Effect를 실행하고 반환 부분을 구현해야 한다. 그리고 현재 상태를 다음 상태로 묘사하는데에 사용된다.
View 정의
Feature를 정의했다면 View를 정의할 차례이다. View에서는 상태를 관찰할 수 있는 Store 객체를 들고 있어야 한다.
Store는 Runtime이라고 했다. State, Action, Reducer를 가지고 있는 친구인데 Store를 실제로 관찰하거나 Store에 액션을 전송하기 위해서는 ViewStore로 한 번 감싸져야 한다. ViewStore가 ObservableObject이기 때문이다. Store를 ViewStore로 변환해주는 역할을 하는 것이 WithViewStore 구조체이다.