swiftui · note · architecture · performance
Why onAppear Is Not Lifecycle
Context
onAppear can run multiple times, so treating it as a one-time lifecycle hook causes fragile behavior.
The snippet
struct FeedView: View {
@State private var hasLoaded = false
var body: some View {
List(0..<20, id: \.self) { index in
Text("Row \(index)")
}
.task {
guard !hasLoaded else { return }
hasLoaded = true
await loadFeed()
}
}
private func loadFeed() async {
// async fetch
}
}
Why this works
task models asynchronous work explicitly and composes better with cancellation than assuming onAppear means “screen started once.”
Use it when…
- you need first-load behavior guarded by state
- you need cancellation-aware async work
- the view may appear/disappear repeatedly
Avoid it when…
- you put heavy synchronous work in
bodyoronAppear - you assume one appearance equals one lifetime
- you trigger network calls without idempotency guards
Takeaway: Treat onAppear as a visibility signal, not as lifecycle truth.