반응형
Transform
func transform(action: Observable<Action>) -> Observable<Action>
func transform(mutation: Observable<Mutation>) -> Observable<Mutation>
func transform(state: Observable<State>) -> Observable<State>
Transform의 함수 종류는 총 3개가 있다.
transform 함수는 개발자가 Action, State 및 Mutation 스트림을 조작할 수 있게 해준다.
- 부작용 처리: 로깅, 분석 또는 네트워크 요청과 같은 부작용 처리.
- 복잡한 반응형 흐름 구성: 여러 작업을 체이닝하여 구성.
- 액션 및 상태 필터링 또는 수정: 더 예측 가능한 상태 관리 흐름을 만들기 위해.
- Global State와의 상호작용: 여러 Reactor가 공통 상태를 공유하고 관리
transform 함수는 세 가지 주요 변환 포인트를 제공한다.:
- transform(action:): 들어오는 action을 바로 가로채서 변환할 수 있다.
- transform(mutation:): 들어오는 mutation을 바로 가로채서 변환할 수 있다.
- transform(state:): 들어오는 state 스트림을 바로 가로채서 변환할 수 있다.
Global States
Redux와 달리 ReactorKit은 글로벌 앱 상태를 정의하지 않는다.
ReactorKit의 흐름은 일반적으로, , Action → Mutation → State 이다.
그렇다는 것은 즉, global state를 정의하기 위해 어떠한 방법이든 자유롭게 사용 가능하다는것과
global state를 사용하기 위해 BehaviorSubject, PublishSubject 심지어는 reactor를 사용할 수 있음을 의미한다.
ReactorKit은 앱에서 특정 기능을 위해 global state를 강요하지 않는다.
그렇다면, Global State는 뭐고, 어떻게 활용할까?
global State는 여러 Reactor에서 이 subject의 value가 변할때마다 알림을 받거나 사용자 정보에 접근하고 싶어하는 경우를 예로 들 수 있다.
var currentUser: BehaviorSubject<User> // global state
func transform(mutation: Observable<Mutation>) -> Observable<Mutation> {
return Observable.merge(mutation, currentUser.map(Mutation.setUser))
transform() 은 Action 없이도 Mutation이 가능하도록 도와주는 함수이다.
이를 통해 화면간 데이터 전달 또한 가능하다.
import UIKit
import ReactorKit
import RxSwift
import RxCocoa
class MainViewController: UIViewController, View {
var disposeBag = DisposeBag()
let textField = UITextField()
let submitButton = UIButton()
init(reactor: MainReactor) {
super.init(nibName: nil, bundle: nil)
self.reactor = reactor
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
// UI 설정
view.addSubview(textField)
view.addSubview(submitButton)
// 레이아웃 설정 (생략)
}
func bind(reactor: MainReactor) {
// 액션 바인딩
submitButton.rx.tap
.map { Reactor.Action.submitText(self.textField.text ?? "") }
.bind(to: reactor.action)
.disposed(by: disposeBag)
}
}
class MainReactor: Reactor {
enum Action {
case submitText(String)
}
enum Mutation {
case setText(String)
}
struct State {
var text: String = ""
}
let initialState = State()
func mutate(action: Action) -> Observable<Mutation> {
switch action {
case .submitText(let text):
return Observable.just(Mutation.setText(text))
}
}
func reduce(state: State, mutation: Mutation) -> State {
var newState = state
switch mutation {
case .setText(let text):
newState.text = text
}
return newState
}
func transform(mutation: Observable<Mutation>) -> Observable<Mutation> {
return mutation.do(onNext: { mutation in
switch mutation {
case .setText(let text):
AppState.shared.sharedText = text
}
})
}
}
반응형
'iOS > ReactorKit' 카테고리의 다른 글
[ReactorKit] @Pulse 키워드 (0) | 2024.10.25 |
---|---|
[ReactortKit] ReactortKit 슥 알아보기 (1) | 2024.06.09 |