0
0
Ios-swiftHow-ToBeginner ยท 3 min read

How to Use @StateObject in SwiftUI: Simple Guide

Use @StateObject in SwiftUI to create and own an observable object inside a view, ensuring it stays alive and updates the UI when its data changes. Declare it with @StateObject var and assign your observable class instance to it.
๐Ÿ“

Syntax

The @StateObject property wrapper is used to create and own an observable object in a SwiftUI view. It keeps the object alive and updates the view when the object changes.

Syntax parts:

  • @StateObject: Declares ownership of the observable object.
  • var: The variable that holds the object.
  • = ClassName(): Initializes the observable object.
swift
@StateObject var viewModel = MyViewModel()
๐Ÿ’ป

Example

This example shows a simple counter app using @StateObject. The CounterViewModel class holds the count and updates the UI when the count changes.

swift
import SwiftUI

class CounterViewModel: ObservableObject {
  @Published var count = 0

  func increment() {
    count += 1
  }
}

struct ContentView: View {
  @StateObject var viewModel = CounterViewModel()

  var body: some View {
    VStack(spacing: 20) {
      Text("Count: \(viewModel.count)")
        .font(.largeTitle)
      Button("Increment") {
        viewModel.increment()
      }
    }
    .padding()
  }
}
Output
A screen showing "Count: 0" and a button labeled "Increment". Each tap on the button increases the count number by 1 and updates the text.
โš ๏ธ

Common Pitfalls

Common mistakes when using @StateObject include:

  • Using @StateObject in child views instead of the parent, causing multiple instances and losing state.
  • Using @ObservedObject when you should use @StateObject to own the object.
  • Re-initializing the object inside the view body, which resets state on every update.

Always create @StateObject once per view lifecycle.

swift
/* Wrong way: Re-initializing in body */
struct WrongView: View {
  @StateObject var viewModel = CounterViewModel()

  var body: some View {
    // This recreates viewModel every time, losing state
    let viewModel = CounterViewModel()
    Text("Count: \(viewModel.count)")
  }
}

/* Right way: Initialize once */
struct RightView: View {
  @StateObject var viewModel = CounterViewModel()

  var body: some View {
    Text("Count: \(viewModel.count)")
  }
}
๐Ÿ“Š

Quick Reference

@StateObject Quick Tips:

  • Use @StateObject to create and own an observable object in a view.
  • Initialize it once when the view is created.
  • Use @ObservedObject to reference an object owned elsewhere.
  • Do not re-initialize inside the body property.
  • Works only with classes conforming to ObservableObject.
โœ…

Key Takeaways

Use @StateObject to create and own an observable object inside a SwiftUI view.
Initialize @StateObject only once to preserve state across view updates.
Use @ObservedObject to reference observable objects owned by other views.
Avoid re-initializing @StateObject inside the view body to prevent losing state.
Your observable object class must conform to ObservableObject and use @Published for properties.