ifLet(_:action:then:fileID:filePath:line:column:)

Embeds a child reducer in a parent domain that works on an optional property of parent state.

IfLetReducer.swift:59
@warn_unqualified_access func ifLet<WrappedState, WrappedAction, Wrapped>(_ toWrappedState: WritableKeyPath<State, WrappedState?>, action toWrappedAction: CaseKeyPath<Action, WrappedAction>, @ReducerBuilder<WrappedState, WrappedAction> then wrapped: () -> Wrapped, fileID: StaticString = #fileID, filePath: StaticString = #filePath, line: UInt = #line, column: UInt = #column) -> some Reducer<State, Action> where WrappedState == Wrapped.State, WrappedAction == Wrapped.Action, Wrapped : Reducer

Parameters

toWrappedState

A writable key path from parent state to a property containing optional child state.

toWrappedAction

A case path from parent action to a case containing child actions.

wrapped

A reducer that will be invoked with child actions against non-optional 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 a piece of optional child state, then it can perform its core logic and the child’s logic by using the ifLet operator:

@Reducer
struct Parent {
  struct State {
    var child: Child.State?
    // ...
  }
  enum Action {
    case child(Child.Action)
    // ...
  }

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

The ifLet operator does a number of things to try to enforce correctness:

  • It 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 nil out the child state, in which case the child feature would not be able to react to that action. That can cause subtle bugs.

  • It automatically cancels all child effects when it detects the child’s state is nil’d out.

  • Automatically nils out child state when an action is sent for alerts and confirmation dialogs.

See Reducer/ifLet(_:action:destination:fileID:filePath:line:column:)-4ub6q for a more advanced operator suited to navigation.