What is @State in SwiftUI?

@State is a property wrapper used to declare state variables in a view. When the state changes, SwiftUI automatically re-renders the parts of the view affected by that state. It is suitable for simple, local state management within a view.

The @State property wrapper in SwiftUI is used to declare a piece of mutable state that is local to a particular view. When you mark a property with @State, SwiftUI manages the storage for that property and watches it for changes. Whenever the value of a @State property changes, SwiftUI automatically re-renders the parts of the view that depend on that state, keeping the UI in sync with the underlying data.

Explanation:

  • @State is used for simple, local state management within a view.
  • The state is private to the view and is not intended to be shared directly with other views.
  • SwiftUI treats views as value types and rebuilds them often, but the @State wrapper ensures the state persists across these rebuilds.
  • Behind the scenes, SwiftUI synthesizes additional properties for every @State property: the wrapped value (the regular property), a projected value (called with $ prefix) which provides a binding, and the property wrapper struct itself.
  • Usage of @State allows your UI to reactively update when the state changes, eliminating the need for manual update calls.

When to use @State

  • For UI elements that hold data locally, such as toggle switches, input fields, counters, or flags.
  • When the state is only relevant within a single view and does not need to be passed or shared.
import SwiftUI

struct CounterView: View {
    // Declare a state variable
    @State private var count: Int = 0 
    var body: some View {
        VStack(spacing: 20) {
            Text("Count: \(count)") 
               // UI reflects the state
                .font(.largeTitle)
            Button("Increment") {
                count += 1  // Modify the state
            }
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(8)

            Button("Decrement") {
                count -= 1
            }
            .padding()
            .background(Color.red)
            .foregroundColor(.white)
            .cornerRadius(8)
        }
    }
}
  • In this example, count is marked with @State. When the buttons are tapped, count updates, and SwiftUI automatically refreshes the Text view to show the new count.
  • The state is owned and managed by CounterView only.
Key points:
  • Manages private, mutable state internal to a view.
  • Changes trigger automatic UI updates (view invalidation and re-render).
  • Enables reactive programming model in SwiftUI.
  • Provides a binding through the projected value ($propertyName) useful for two-way data binding.
  • Not intended for sharing state between different views – use @Binding or @ObservedObject for that.

These aspects of @State make it one of the fundamental building blocks in SwiftUI for controlling user interface behavior based on dynamic data.