Skip to content

Instantly share code, notes, and snippets.

@AlexanderBollbach
Created September 10, 2019 02:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlexanderBollbach/c6e85172ace5f16132cd51b4301cf45a to your computer and use it in GitHub Desktop.
Save AlexanderBollbach/c6e85172ace5f16132cd51b4301cf45a to your computer and use it in GitHub Desktop.
import SwiftUI
final class Store<Value, Action>: ObservableObject {
let reducer: (inout Value, Action) -> Void
@Published private(set) var value: Value
init(initialValue: Value, reducer: @escaping (inout Value, Action) -> Void) {
self.reducer = reducer
self.value = initialValue
}
func send(_ action: Action) {
self.reducer(&self.value, action)
}
}
extension Store {
public func send<LocalValue>(
_ action: @escaping (LocalValue) -> Action,
binding keyPath: KeyPath<Value, LocalValue>
) -> Binding<LocalValue> {
Binding(
get: { self.value[keyPath: keyPath] },
set: { self.send(action($0)) }
)
}
}
struct AppState {
var pickerVal = "picker"
var textVal = "picker"
}
enum AppAction {
case updatePickerVal(String)
case updateTextVal(String)
}
func reducer(state: inout AppState, action: AppAction) {
switch action {
case let .updatePickerVal(val): state.pickerVal = val
case let .updateTextVal(val): state.textVal = val
}
print(state)
}
let store: Store<AppState, AppAction> = Store(initialValue: AppState(), reducer: reducer)
struct Test: View {
var body: some View {
HStack {
Picker.init(selection: store.send({ .updatePickerVal($0) }, binding: \.pickerVal), label: Text("pick: ")) {
Text("bar").tag(1)
Text("baz").tag(2)
}
TextField("type: ", text: store.send({ .updateTextVal($0) }, binding: \.textVal))
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View { Test() }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment