ViewStore

@dynamicMemberLookup
public final class ViewStore<State, Action> : ObservableObject

A ViewStore is an object that can observe state changes and send actions. They are most commonly used in views, such as SwiftUI views, UIView or UIViewController, but they can be used anywhere it makes sense to observe state and send actions.

In SwiftUI applications, a ViewStore is accessed most commonly using the WithViewStore view. It can be initialized with a store and a closure that is handed a view store and must return a view to be rendered:

var body: some View {
  WithViewStore(self.store) { viewStore in
    VStack {
      Text("Current count: \(viewStore.count)")
      Button("Increment") { viewStore.send(.incrementButtonTapped) }
    }
  }
}

In UIKit applications a ViewStore can be created from a Store and then subscribed to for state updates:

let store: Store<State, Action>
let viewStore: ViewStore<State, Action>

init(store: Store<State, Action>) {
  self.store = store
  self.viewStore = ViewStore(store)
}

func viewDidLoad() {
  super.viewDidLoad()

  self.viewStore.publisher.count
    .sink { [weak self] in self?.countLabel.text = $0 }
    .store(in: &self.cancellables)
}

@objc func incrementButtonTapped() {
  self.viewStore.send(.incrementButtonTapped)
}
  • A publisher of state.

    Declaration

    Swift

    public let publisher: StorePublisher<State>
  • Initializes a view store from a store.

    Declaration

    Swift

    public init(
      _ store: Store<State, Action>,
      removeDuplicates isDuplicate: @escaping (State, State) -> Bool
    )

    Parameters

    store

    A store.

    isDuplicate

    A function to determine when two State values are equal. When values are equal, repeat view computations are removed.

  • The current state.

    Declaration

    Swift

    public private(set) var state: State { get set }
  • Returns the resulting value of a given key path.

    Declaration

    Swift

    public subscript<LocalState>(dynamicMember keyPath: KeyPath<State, LocalState>) -> LocalState { get }
  • Sends an action to the store.

    ViewStore is not thread safe and you should only send actions to it from the main thread. If you are wanting to send actions on background threads due to the fact that the reducer is performing computationally expensive work, then a better way to handle this is to wrap that work in an Effect that is performed on a background thread so that the result can be fed back into the store.

    Declaration

    Swift

    public func send(_ action: Action)

    Parameters

    action

    An action.

  • Derives a binding from the store that prevents direct writes to state and instead sends actions to the store.

    The method is useful for dealing with SwiftUI components that work with two-way Bindings since the Store does not allow directly writing its state; it only allows reading state and sending actions.

    For example, a text field binding can be created like this:

    struct State { var name = "" }
    enum Action { case nameChanged(String) }
    
    TextField(
      "Enter name",
      text: viewStore.binding(
        get: { $0.name },
        send: { Action.nameChanged($0) }
      )
    )
    

    Declaration

    Swift

    public func binding<LocalState>(
      get: @escaping (State) -> LocalState,
      send localStateToViewAction: @escaping (LocalState) -> Action
    ) -> Binding<LocalState>

    Parameters

    get

    A function to get the state for the binding from the view store’s full state.

    localStateToViewAction

    A function that transforms the binding’s value into an action that can be sent to the store.

    Return Value

    A binding.

  • Derives a binding from the store that prevents direct writes to state and instead sends actions to the store.

    The method is useful for dealing with SwiftUI components that work with two-way Bindings since the Store does not allow directly writing its state; it only allows reading state and sending actions.

    For example, an alert binding can be dealt with like this:

    struct State { var alert: String? }
    enum Action { case alertDismissed }
    
    .alert(
      item: self.store.binding(
        get: { $0.alert },
        send: .alertDismissed
      )
    ) { alert in Alert(title: Text(alert.message)) }
    

    Declaration

    Swift

    public func binding<LocalState>(
      get: @escaping (State) -> LocalState,
      send action: Action
    ) -> Binding<LocalState>

    Parameters

    get

    A function to get the state for the binding from the view store’s full state.

    action

    The action to send when the binding is written to.

    Return Value

    A binding.

  • Derives a binding from the store that prevents direct writes to state and instead sends actions to the store.

    The method is useful for dealing with SwiftUI components that work with two-way Bindings since the Store does not allow directly writing its state; it only allows reading state and sending actions.

    For example, a text field binding can be created like this:

    struct State { var name = "" }
    enum Action { case nameChanged(String) }
    
    TextField(
      "Enter name",
      text: viewStore.binding(
        send: { Action.nameChanged($0) }
      )
    )
    

    Declaration

    Swift

    public func binding(
      send localStateToViewAction: @escaping (State) -> Action
    ) -> Binding<State>

    Parameters

    localStateToViewAction

    A function that transforms the binding’s value into an action that can be sent to the store.

    Return Value

    A binding.

  • Derives a binding from the store that prevents direct writes to state and instead sends actions to the store.

    The method is useful for dealing with SwiftUI components that work with two-way Bindings since the Store does not allow directly writing its state; it only allows reading state and sending actions.

    For example, an alert binding can be dealt with like this:

    struct State { var alert: String? }
    enum Action { case alertDismissed }
    
    .alert(
      item: self.store.binding(
        send: .alertDismissed
      )
    ) { alert in Alert(title: Text(alert.message)) }
    

    Declaration

    Swift

    public func binding(send action: Action) -> Binding<State>

    Parameters

    action

    The action to send when the binding is written to.

    Return Value

    A binding.

Available where State: Equatable

  • Undocumented

    Declaration

    Swift

    public convenience init(_ store: Store<State, Action>)