Skip to content

Instantly share code, notes, and snippets.

@AlexanderBollbach
Created September 10, 2019 02:38
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/10452e09edb3add9369b9dad07fd18a2 to your computer and use it in GitHub Desktop.
Save AlexanderBollbach/10452e09edb3add9369b9dad07fd18a2 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 val = "42" }
enum AppAction { case updateVal(String) }
func reducer(state: inout AppState, action: AppAction) {
switch action {
case let .updateVal(val): state.val = val
}
print(state)
}
let store: Store<AppState, AppAction> = Store(initialValue: AppState(), reducer: reducer)
struct Test: View {
@State var val: String = ""
var body: some View {
Picker.init("pick",
selection: store.send(
{ newVal in .updateVal(newVal) },
binding: \.self.val)
){
Text("bar").tag(1)
Text("baz").tag(2)
}
}
}
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