open class Store<S> : Publisher

Combine-based state management. Enables dispatching of actions, executing reducers, performing side-effects, and listening for the latest state.

Implements the Publisher protocol, allowing direct subscription for the latest state.

import ReCombine
import Combine

struct CounterView {
    struct Increment: Action {}
    struct Decrement: Action {}

    struct State {
        var count = 0

    static func reducer(state: State, action: Action) -> State {
        var state = state
        switch action {
            case _ as Increment:
                state.count += 1
                return state
            case _ as Decrement:
                state.count -= 1
                return state
                return state

    static let effect = Effect(dispatch: false)  { (actions: AnyPublisher<Action, Never>) in
        actions.ofTypes(Increment.self, Decrement.self).print("Action Dispatched").eraseToAnyPublisher()

let store = Store(reducer: CounterView.reducer, initialState: CounterView.State(), effects: [CounterView.effect])
  • Creates a new Store.



    public init(reducer: @escaping ReducerFn<S>, initialState: S, effects: [Effect] = [])



    a single reducer function which will handle reducing state for all actions dispatched to the store.


    the initial state. This state will be used by consumers before the first action is dispatched.


    action based side-effects. Each Effect element is processed for the lifetime of the Store instance.

  • Dispatch Action to the Store. Calls reducer function with the passed action and previous state to generate a new state.

    Dispatching an action to the Store:

    struct Increment: Action {}
    store.dispatch(action: Increment())



    open func dispatch(action: Action)



    action to call the reducer with.

  • Returns derived data from the application state based on a given selector function.

    Selector functions help return view-specific data from a minimum application state.

    Example: If a view needs the count of characters in a username, instead of storing both the username and the character count in state, store only the username, and use a selector to retrieve the count.{ (state: AppState) in state.username.count })

    To enable reuse, abstract the closure into a separate property.

    let selectUsernameCount = { (state: AppState) in state.username.count }
    // ...



    public func select<V>(_ selector: @escaping (S) -> V) -> AnyPublisher<V, Never> where V : Equatable
  • Registers an effect that processes from when this function is called until the returned AnyCancellable instance in cancelled.

    This can be useful for:

    1. Effects that should not process for the entire lifetime of the Store instance.
    2. Effects that need to capture a particular scope in it’s source closure.

    The following SwiftUI example shows these uses:

    1. Processing the showAlert Effect for the lifetime of the Model only. This is done by storing the returned AnyCancellable instance in cancellableSet. Because cancellableSet is a instance of Set<AnyCancellable>, it will automatically call cancel() when on each element when Model is deinitialized.
    2. Capturing self inside the showAlert Effect’s source closure.

      class Model: ObservableObject {
      @Published var showAlert: Bool = false
      private var cancellableSet: Set<AnyCancellable> = []
      init(store: Store<GetPostError>) {
          let showAlertOnError = Effect(dispatch: false) { actions in
                  .handleEvents(receiveOutput: { [weak self] _ in
                      self?.showAlert = true



    open func register(_ effect: Effect) -> AnyCancellable



    action based side-effect. It is processed until the returned AnyCancellable instance is cancelled.