@State vs a plain var

SwiftUI Junior Swift 5.1+ iOS 17+ Reviewed By Alok Singh

Predict the output

What happens when you build this and tap the button?

struct Counter: View {
    var count = 0
    var body: some View {
        Button("Count: \(count)") {
            count += 1
        }
    }
}
Options
Hint 1 of 1

Is self mutable inside a view's closures?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: C It doesn't compile: cannot assign to property, 'self' is immutable

Correct. Make it @State private var count = 0.

Why not the others?
  • A The label counts up. The closure can't mutate self because the view is an immutable value.
  • B The label stays at 0. It never gets that far; the mutation is rejected at compile time.
  • D It crashes at runtime. Swift catches this at compile time.

30-second answer

A view is an immutable struct that SwiftUI recreates often, so body can't mutate its own stored properties. @State moves the value into storage that SwiftUI owns and keeps for the lifetime of the view's identity. Changing it invalidates the view, and SwiftUI re-runs body.

Practise saying it · 30 s. No recording, just a timer

Explain what @State does.

Say your answer out loud, then check which of these points you covered:

  • Views are immutable values
  • @State is SwiftUI-owned storage
  • Lives as long as the view's identity

Deep dive

Mark @State private: it belongs to this view only.

The initial value is used once; later inits don't reset it.

Pass a binding to children with $value.

If identity changes (if/else branch, .id()), the state is discarded and starts again.

Common mistakes

  • Initializing @State from a parameter and expecting it to follow later parameter changes.
  • Using @State for data owned elsewhere.
  • Making @State public.

Senior take & follow-ups

Seniors explain @State as storage tied to view identity, which sets up the identity question that usually follows.

Follow-up questions

Think of your answer first, then open the hint.

  1. How do you reset @State on purpose?

    Show hint

    Change the view's identity with .id(newValue).

  2. Why does initializing @State from init parameters surprise people?

    Show hint

    Only the first value is used.

Suggest a fix if something here is wrong or out of date.