Home

State and data flow

Choosing the right property wrapper

Every property wrapper answers one question: who owns this value, and who is allowed to change it?

Wrapper Owner Use for
@State this view value-type state this view alone owns
@Binding someone else a two-way handle passed down
@Observable / @Bindable a reference type model objects shared across views
@Environment the environment values handed down implicitly
@Observable
final class Cart {
    var items: [Item] = []
    var total: Decimal { items.reduce(0) { $0 + $1.price } }
}

struct CartView: View {
    @Environment(Cart.self) private var cart

    var body: some View {
        List(cart.items) { ItemRow(item: $0) }
    }
}

@Observable replaced ObservableObject and @Published: instead of the whole object announcing a change, SwiftUI tracks which properties a view actually read and redraws only the views that read the one that changed. A view listing items does not redraw when something unrelated changes.

This is a template chapter. The full text is still being written.