forEach(_:action:element:fileID:filePath:line:column:)

Embeds a child reducer in a parent domain that works on elements of a collection in parent state.

ForEachReducer.swift:120
@warn_unqualified_access func forEach<ElementState, ElementAction, ID, Element>(_ toElementsState: WritableKeyPath<State, IdentifiedArray<ID, ElementState>>, action toElementAction: CaseKeyPath<Action, IdentifiedAction<ID, ElementAction>>, @ReducerBuilder<ElementState, ElementAction> element: () -> Element, fileID: StaticString = #fileID, filePath: StaticString = #filePath, line: UInt = #line, column: UInt = #column) -> some Reducer<State, Action> where ElementState == Element.State, ElementAction == Element.Action, ID : Hashable, ID : Sendable, Element : Reducer

Parameters

toElementsState

A writable key path from parent state to an IdentifiedArray of child state.

toElementAction

A case path from parent action to an IdentifiedAction of child actions.

element

A reducer that will be invoked with child actions against elements of child state.

fileID

The fileID.

filePath

The filePath.

line

The line.

column

The column.

Returns

A reducer that combines the child reducer with the parent reducer.

For example, if a parent feature holds onto an array of child states, then it can perform its core logic and the child’s logic by using the forEach operator:

@Reducer
struct Parent {
  struct State {
    var rows: IdentifiedArrayOf<Row.State>
    // ...
  }
  enum Action {
    case rows(IdentifiedActionOf<Row>)
    // ...
  }

  var body: some Reducer<State, Action> {
    Reduce { state, action in
      // Core logic for parent feature
    }
    .forEach(\.rows, action: \.rows) {
      Row()
    }
  }
}

The forEach forces a specific order of operations for the child and parent features. It runs the child first, and then the parent. If the order was reversed, then it would be possible for the parent feature to remove the child state from the array, in which case the child feature would not be able to react to that action. That can cause subtle bugs.

It is still possible for a parent feature higher up in the application to remove the child state from the array before the child has a chance to react to the action. In such cases a runtime warning is shown in Xcode to let you know that there’s a potential problem.