I've made a subclass of UIHostingController, and in its viewDidLoad() method I've used store.scope(...).ifLet(...).store(in: &cancellables), basically exactly the same as the example here:
I'm sure the scope statement is correct because I copied it from the previously-pure-SwiftUI code where it worked. I've replaced the NavigationLink in my SwiftUI view with a Button that sends the same action that the NavigationLink sent in its selection: binding's send: closure.
The action is received by the reducer as before, and the state is updated as before, but the then: closure passed into Store.ifLet(then:else:) is not called.
Thanks for suggestion! The only meaningful difference between my code and yours was I was subclassing UIHostingController instead of UIViewController and that was actually the problem.
It seems that viewDidLoad is not called on subclasses of UIHostingController. I banged my head against this for so long and didn't actually verify viewDidLoad was being called because, I've never seen that not be the case before and didn't even consider it. Wowzers.