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
@StateObjectin child views instead of the parent, causing multiple instances and losing state. - Using
@ObservedObjectwhen you should use@StateObjectto 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
@StateObjectto create and own an observable object in a view. - Initialize it once when the view is created.
- Use
@ObservedObjectto reference an object owned elsewhere. - Do not re-initialize inside the
bodyproperty. - 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.