swiftui · essay · architecture · state

State vs Binding: A Mental Model

Published January 26, 2026 · Reviewed February 18, 2026 · 3 min read · beginner

The confusion

One of the first recurring questions in SwiftUI is deceptively simple:

“Should this be @State or @Binding?”

You see both used everywhere. Examples work. Previews compile. And yet, as soon as a view grows or gets reused, things start to feel wrong.

Bindings appear where you don’t expect them. State seems to “leak” through your view hierarchy. Refactoring suddenly becomes painful.

The confusion is not about syntax. It’s about ownership.


Why this is confusing

SwiftUI encourages composition: small views, passed around freely, nested deeply.

At the same time, SwiftUI also hides a lot of lifecycle details. Views are value types. Bodies are recomputed. State lives somewhere else.

That makes it easy to accidentally treat @State and @Binding as interchangeable, instead of seeing them for what they actually represent.

Most confusion comes from asking the wrong question:

“Which property wrapper should I use here?”

That question is already too late.


A better mental model

Here is the mental model that removes 90% of the confusion:

@State owns data. @Binding borrows data.

That’s it.

Not:

  • “Use @State in parent views”
  • “Use @Binding in child views”
  • “Use @Binding when passing data”

Those are patterns, not principles.

The principle is ownership.


A small proof

Consider the simplest possible example:

struct CounterView: View {
    @State private var count = 0

    var body: some View {
        Button("Count: \(count)") {
            count += 1
        }
    }
}

This view:

  • creates the state
  • owns the state
  • decides how it changes

Now extract the button:

struct CounterButton: View {
    @Binding var count: Int

    var body: some View {
        Button("Count: \(count)") {
            count += 1
        }
    }
}

Nothing about the behavior changed. What changed is responsibility.

CounterButton does not own count. It only operates on something it was given.

That is exactly what a binding represents.


Why this matters in real apps

Once you internalize ownership, several things become easier immediately:

  • Refactoring You can move views around without redesigning state flow.
  • Reuse Views that use bindings are easier to reuse because they make fewer assumptions.
  • Architecture State naturally rises to the place where it is actually owned.

You stop fighting SwiftUI’s data flow and start working with it.


Where this mental model breaks down

No mental model is perfect.

Some edge cases still require thought:

  • @StateObject vs @ObservedObject
  • @Environment values
  • Derived state computed from multiple sources

But even there, ownership remains the right first question.

If you start by asking who owns this data, the correct abstraction usually reveals itself.


One sentence to remember

State lives where it is owned. Bindings exist only to pass ownership boundaries.