参考URL: SwiftUI-Flux
- CounterView.swift
import SwiftUI
struct CounterView : View {
enum Action {
case increment
case decrement
}
@State var store = Store<Int, Action>(initial: 0) { count, action in
switch action {
case .increment:
return count + 1
case .decrement:
return max(0, count - 1)
}
}
var body: some View {
VStack {
Text("\(store.state)")
HStack {
Button(action: { self.store.dispatch(action: .decrement) }) {
Text("Decrement")
}
Button(action: { self.store.dispatch(action: .increment) }) {
Text("Increment")
}
}
}
}
}
#if DEBUG
struct CounterView_Previews : PreviewProvider {
static var previews: some View {
CounterView()
}
}
#endif
- Store.swift
import SwiftUI
import Combine
final class Store<State, Action>: BindableObject {
typealias Reducer = (State, Action) -> State
let didChange = PassthroughSubject<State, Never>()
var state: State {
lock.lock()
defer { lock.unlock() }
return _state
}
private let lock = NSLock()
private let reducer: Reducer
private var _state: State
init(initial state: State, reducer: @escaping Reducer) {
_state = state
self.reducer = reducer
}
func dispatch(action: Action) {
lock.lock()
let newState = reducer(_state, action)
_state = newState
lock.unlock()
didChange.send(newState)
}
}
イメージ |
---|