Created
December 2, 2021 17:53
-
-
Save alexito4/dbb2c5e87d6ad3540db864a3a64ce1ae to your computer and use it in GitHub Desktop.
Why does the body of FeatureView get recomputed when the alert is shown/dismissed? There is no @State on that view.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@main | |
struct PreviewApp: App { | |
var body: some Scene { | |
WindowGroup { | |
NavigationView { | |
AlertContainer { route in | |
FeatureView(route: route) | |
} | |
} | |
let _ = print(type(of: self), "body") | |
} | |
} | |
} | |
struct FeatureView: View { | |
let route: Binding<String?> | |
var body: some View { | |
Button("Tap") { | |
route.wrappedValue = "route" | |
} | |
let _ = print(type(of: self), "body") | |
} | |
} | |
struct AlertContainer<C: View>: View { | |
@State var route: String? | |
@ViewBuilder let content: (Binding<String?>) -> C | |
var body: some View { | |
let _ = print(type(of: self), "body") | |
content($route) | |
.alert(isPresented: $route.hasValue(), content: { | |
Alert(title: Text("Open \(String(describing: route))")) | |
}) | |
} | |
} | |
extension Binding { | |
func hasValue<T>() -> Binding<Bool> where Value == Optional<T> { | |
.init { | |
self.wrappedValue != nil | |
} set: { newValue in | |
if newValue == false { | |
self.wrappedValue = nil | |
} | |
} | |
} | |
} |
I was not expecting FeatureView.body to be called when the alert changes since that view doesn't have any observable state.
Binding conforms to DynamicProperty so from SwiftUI tracking perspective its like State.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://twitter.com/alexito4/status/1466453681197522945