Navigation: Going Back sends action twice

I'm not sure if this is related to this SwiftUI bug, but I haven't been able to fix it with the advice in that link.

For some reason, when pressing the back button (or swiping) in a navigation stack the setter in the binding gets called twice, which means the setNavigation(nil) action is sent twice.

This happens for every example in the repo. It's usually not a big deal, but if you are doing something in the reducer when the navigation goes back it could be problematic.

The way I fixed it is by taking advantage on the fact that all state is equatable and adding this override to the ViewStore method:

public func binding<LocalState> (
    get: @escaping (State) -> LocalState,
    send localStateToViewAction: @escaping (LocalState) -> Action
) -> Binding<LocalState> where LocalState: Equatable {
        get: { get(self.state) },
        set: { newLocalState, transaction in
            guard newLocalState != get(self.state) else { return }
            withAnimation(transaction.disablesAnimations ? nil : transaction.animation) {

Does this make sense or am I missing something?

I believe this is another SwiftUI bug, and I don't think it's related to the other bug you are referencing. Others have also come across this bug (outside the TCA world) and had to work around. For example, @inamiy works around it in one of his libraries by defining a removeDuplicates method on Binding. That may be a good approach for you instead of changing the binding method on ViewStore (until the bug is fixed in SwiftUI).


Yep! That works too. Thanks.

Terms of Service

Privacy Policy

Cookie Policy