Skip to content

Fix: alert action not routed to reducer in MultipleDestinations tutorial - #3959

Open
carlosypunto wants to merge 1 commit into
pointfreeco:mainfrom
carlosypunto:fix/multiple-destinations-alert-tutorial
Open

Fix: alert action not routed to reducer in MultipleDestinations tutorial#3959
carlosypunto wants to merge 1 commit into
pointfreeco:mainfrom
carlosypunto:fix/multiple-destinations-alert-tutorial

Conversation

@carlosypunto

Copy link
Copy Markdown

What

02-02-02-code-0014.swift in the "Multiple destinations" tutorial step presents the alert like this:

.alert($store.scope(\.$destination, action: \.destination).alert)

This single-argument call resolves to the alert(_ state:) overload in swift-navigation that's deprecated as of 2.7.0, since it discards the button action instead of forwarding it:

public func alert<Value>(_ state: Binding<AlertState<Value>?>) -> some View {
  alert(state) { _ in }
}

As a result, tapping a button in the alert never reaches the reducer — and building the tutorial's code as written produces this deprecation warning in Xcode:

alert deprecation warning 'alert' is deprecated: Binding to alert state must not ignore actions; provide an explicit trailing action handler`

Why this happens

With the enum-scope API introduced in TCA 1.25, scoping into a non-reducer case of a destination enum (like .alert) now returns direct access to the state (a plain Binding<AlertState<Value>?>) rather than a Store-wrapped binding. That means the action handler is no longer wired automatically and must be supplied explicitly.

Suggested fix

.alert($store.scope(state: \.$destination, action: \.destination).alert) { action in
  if let action {
    store.send(.destination(.presented(.alert(action))))
  }
}

I confirmed locally that the current tutorial code compiles with the deprecation warning above and drops the alert's action, while this change compiles cleanly and correctly routes the action to the reducer.

Note

I'm learning TCA, so please let me know if there's a more idiomatic way to route the action here that I'm missing — happy to update the PR.

The tutorial's alert modifier was calling `.alert(_ state:)` with a
single argument, which resolves to the overload in SwiftUINavigation
that has been deprecated (deprecated after swift-navigation 2.7.0)
because it silently discards the alert's button action:

    public func alert<Value>(_ state: Binding<AlertState<Value>?>) -> some View {
      alert(state) { _ in }
    }

Since TCA 1.25's enum-scope API returns direct access to the alert
state (not wrapped in a `Store`) for non-reducer destination cases,
callers must supply an explicit trailing action handler to route the
tapped button's action back into the store. Without it, the action is
dropped and never reaches the reducer.

This adds the explicit handler, forwarding the alert action through
`store.send(.destination(.presented(.alert(action))))`, which resolves
the deprecation warning and makes button taps in the alert actually
reach the reducer.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant