Skip to main content
An Effect represents a unit of asynchronous work that can emit actions back into the system. Effects are returned from reducers to perform side effects like network requests, timers, database operations, and more.

Type Definition

public struct Effect<Action>: Sendable

Creating Effects

None

none
static var
An effect that does nothing and completes immediately. Useful for situations where you must return an effect, but you don’t need to do anything.
case .cancelButtonTapped:
  state.isLoading = false
  return .none

Run

run(priority:name:operation:catch:)
static func
Wraps an asynchronous unit of work that can emit actions any number of times in an effect.Parameters:
  • priority: Priority of the underlying task. If nil, the priority will come from Task.currentPriority
  • name: An optional name to associate with the task that runs this effect
  • operation: The operation to execute
  • handler: An error handler, invoked if the operation throws an error other than CancellationError
Returns: An effect wrapping the given asynchronous work.
public static func run(
  priority: TaskPriority? = nil,
  name: String? = nil,
  operation: @escaping @Sendable (_ send: Send<Action>) async throws -> Void,
  catch handler: (@Sendable (_ error: any Error, _ send: Send<Action>) async -> Void)? = nil
) -> Self

Send

send(_:)
static func
Initializes an effect that immediately emits the action passed in.
We do not recommend using Effect.send to share logic. Instead, limit usage to child-parent communication, where a child may want to emit a “delegate” action for a parent to listen to.
public static func send(_ action: Action) -> Self
send(_:animation:)
static func
Initializes an effect that immediately emits the action passed in with animation.Parameters:
  • action: The action that is immediately emitted by the effect
  • animation: An animation
public static func send(_ action: Action, animation: Animation? = nil) -> Self

Usage Examples

Basic Run Effect

Attach to an async sequence in a dependency client:
struct EventsClient {
  var events: () -> any AsyncSequence<Event, Never>
}

// In your reducer:
case .startButtonTapped:
  return .run { send in
    for await event in self.events() {
      send(.event(event))
    }
  }

Error Handling

The closure provided to run is allowed to throw, but any non-cancellation errors thrown will cause a runtime warning. To catch errors, use the catch trailing closure:
case .loadButtonTapped:
  state.isLoading = true
  return .run { send in
    let data = try await apiClient.fetchData()
    await send(.dataLoaded(data))
  } catch: { error, send in
    await send(.errorOccurred(error))
  }

Network Request Example

case .searchQueryChanged(let query):
  state.query = query
  return .run { send in
    try await clock.sleep(for: .seconds(0.3))
    let results = try await apiClient.search(query)
    await send(.searchResponse(.success(results)))
  } catch: { error, send in
    await send(.searchResponse(.failure(error)))
  }

Composing Effects

Merge

merge(_:)
static func
Merges a variadic list of effects together into a single effect, which runs the effects at the same time.
public static func merge(_ effects: Self...) -> Self
public static func merge(_ effects: some Sequence<Self>) -> Self
Example:
return .merge(
  .run { send in await send(.trackAnalytics) },
  .run { send in await send(.updateCache) }
)
merge(with:)
func
Merges this effect and another into a single effect that runs both at the same time.
public func merge(with other: Self) -> Self

Concatenate

concatenate(_:)
static func
Concatenates a variadic list of effects together into a single effect, which runs the effects one after the other.
public static func concatenate(_ effects: Self...) -> Self
public static func concatenate(_ effects: some Collection<Self>) -> Self
Example:
return .concatenate(
  .run { send in await send(.startAnimation) },
  .run { send in await send(.finishAnimation) }
)
concatenate(with:)
func
Concatenates this effect and another into a single effect that first runs this effect, and after it completes or is cancelled, runs the other.
public func concatenate(with other: Self) -> Self

Map

map(_:)
func
Transforms all elements from the upstream effect with a provided closure.
public func map<T>(_ transform: @escaping @Sendable (Action) -> T) -> Effect<T>
Example:
return ChildFeature()
  .reduce(into: &state.child, action: childAction)
  .map { .child($0) }

Send Type

@MainActor
public struct Send<Action>: Sendable
A type that can send actions back into the system when used from Effect.run. This type implements callAsFunction so that you invoke it as a function:
return .run { send in
  await send(.started)
  for await event in self.events {
    send(.event(event))
  }
  await send(.finished)
}

Methods

callAsFunction(_:)
(Action) -> Void
Sends an action back into the system from an effect.
public func callAsFunction(_ action: Action)
callAsFunction(_:animation:)
(Action, Animation?) -> Void
Sends an action back into the system from an effect with animation.
public func callAsFunction(_ action: Action, animation: Animation?)
callAsFunction(_:transaction:)
(Action, Transaction) -> Void
Sends an action back into the system from an effect with transaction.
public func callAsFunction(_ action: Action, transaction: Transaction)

Type Aliases

EffectOf
typealias
A convenience type alias for referring to an effect of a given reducer’s domain.
public typealias EffectOf<R: Reducer> = Effect<R.Action>
Instead of specifying the action:
let effect: Effect<Feature.Action>
You can specify the reducer:
let effect: EffectOf<Feature>

Build docs developers (and LLMs) love