[Swift] ReactorKit에서 사용하는 주요 컴포넌트와 그 역할: Reactor, Action, Mutation 등 ReactorKit의 주요 컴포넌트를
Swift에서 ReactorKit 사용하는 법
ReactorKit는 Swift 개발자들이 비즈니스 로직을 깔끔하고 직관적으로 관리할 수 있도록 돕는 라이브러리입니다. 이 글에서는 ReactorKit의 주요 컴포넌트인 Reactor, Action, Mutation에 대해 자세히 설명하고, 각각의 역할과 사용 방법을 다룹니다.
ReactorKit의 개요
ReactorKit는 Model-View-ViewModel(MVVM) 패턴에 Reactor라는 개념을 추가하여, 상태(state)를 관리하고, 변화를 추적하며, 간단한 비즈니스 로직을 구현할 수 있게 해줍니다. ReactorKit는 Reactor
, Action
, Mutation
, State
라는 네 가지 주요 요소로 구성되어 있습니다.
Reactor
Reactor
는 앱 상태를 추상화한 것으로, 상태 변화를 관리하고, 비즈니스 로직을 포함합니다. Reactor
는 다음과 같은 프로퍼티와 메소드를 가집니다:
initialState
: 초기 상태를 정의합니다.action
: 사용자로부터 발생하는 모든 액션을 받아들입니다.mutation
: 액션(action)을 변환하여 상태 변화를 만드는 반응 객체입니다.state
: 최종 상태를 나타내며, 화면에 반영됩니다.
swiftimport ReactorKit import RxSwift class MyReactor: Reactor { enum Action { case doSomething } enum Mutation { case setLoading(Bool) case setResult(String) } struct State { var isLoading: Bool = false var result: String? } let initialState: State = State() func mutate(action: Action) -> Observable<Mutation> { switch action { case .doSomething: return Observable.concat([ Observable.just(Mutation.setLoading(true)), // API call or some async task Observable.just(Mutation.setResult("Hello, ReactorKit")), Observable.just(Mutation.setLoading(false)) ]) } } func reduce(state: State, mutation: Mutation) -> State { var newState = state switch mutation { case .setLoading(let isLoading): newState.isLoading = isLoading case .setResult(let result): newState.result = result } return newState } }
Action
Action
은 사용자 인터페이스에서 발동되는 모든 이벤트의 열거형입니다. 여기에는 버튼 클릭, 텍스트 입력, 스크롤 등의 이벤트가 포함될 수 있습니다. Reactor
는 Action
을 받아 Mutation
으로 변환합니다.
swiftclass MyReactor: Reactor { enum Action { case buttonClicked case textTyped(String) } // ... other code }
Mutation
Mutation
은 Action
이 실제로 변경되어 State
로 반영되기 전에 잠시 나타나는 변형입니다. 즉, Action
이 상태 변화에 어떤 영향을 미칠지 결정하는 중간 단계입니다.
swiftclass MyReactor: Reactor { enum Mutation { case setLoading(Bool) case updateText(String) } // ... other code }
State
State
는 화면에 반영될 최종 상태를 나타내는 구조체입니다. Reactor
는 지속적으로 State
를 관리하고 업데이트하여 화면과 상호작용합니다.
swiftstruct State { var isLoading: Bool = false var text: String = "" }
ReactorKit의 실사용 예제
완전한 예제를 통해 ReactorKit의 사용법을 복습해보겠습니다. 이 예제에서는 버튼 클릭 시 API 호출을 시도하고, 결과를 화면에 표시하는 간단한 기능을 구현합니다.
swiftimport UIKit import ReactorKit import RxSwift import RxCocoa class ViewController: UIViewController, View { var disposeBag = DisposeBag() let button = UIButton() let resultLabel = UILabel() override func viewDidLoad() { super.viewDidLoad() self.view.addSubview(button) self.view.addSubview(resultLabel) self.button.setTitle("Fetch Data", for: .normal) } func bind(reactor: MyReactor) { // Action button.rx.tap .map { Reactor.Action.doSomething } .bind(to: reactor.action) .disposed(by: disposeBag) // State reactor.state .map { $0.result } .bind(to: resultLabel.rx.text) .disposed(by: disposeBag) } }
이 코드는 button
이 클릭될 때 doSomething
이라는 Action
을 트리거하고, resultLabel
에는 state.result
가 업데이트될 때마다 텍스트를 변경합니다.
ReactorKit는 Swift로 구현된 애플리케이션에서 비즈니스 로직을 명확하게 관리할 수 있게 해줍니다. 이번 글에서는 ReactorKit의 주요 컴포넌트인 Reactor, Action, Mutation에 대해 설명했습니다. 이를 통해 더 깔끔하고 유지보수하기 쉬운 코드를 작성할 수 있기를 바랍니다.