Skip to content

State and StateObject in SwiftUI

In this post you will learn about @StateObject and @State in SwiftUI!

Understanding @StateObject: Managing Complex, Persistent Data

@StateObject is used to instantiate and manage the lifecycle of an observable object that owns significant data or logic that persists for the lifetime of the view. It’s best used when the data model needs to persist and be shared across multiple views or when the data model performs tasks that affect the app state globally.

Example: TodoList Manager

Consider a simple todo list manager where tasks can be added, and each task has a completed state.

import SwiftUI

@Observable
class TaskManager: Observable {
   var tasks: [String] = []
}

struct TaskListView: View {
    @StateObject private var taskManager = TaskManager()

    var body: some View {
        List {
            ForEach(taskManager.tasks, id: \.self) { task in
                Text(task)
            }
            Button("Add Task") {
                taskManager.tasks.append("Task \(taskManager.tasks.count + 1)")
            }
        }
    }
}

Here, TaskManager is an observable object that manages our tasks. @StateObject is used to instantiate it in TaskListView, ensuring that it stays alive and updates the view as tasks are added.

Understanding @State: For Transient, Local View Data

@State is a property wrapper designed for simpler, view-specific state management. It is ideal for transient data that only exists for the life of the view and does not need to be shared across different parts of the app.

Example: Simple Counter

Let’s implement a simple counter that increments when a button is tapped, demonstrating @State.

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

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

In this example, count is a simple integer managed by @State. It’s perfect for @State as it’s specific to CounterView and doesn’t need to be shared with other parts of the app.

Choosing Between @StateObject and @State

  • Use @StateObject for managing complex data models that need to persist beyond the view, are shared among multiple views, or have business logic.
  • Use @State for simple, ephemeral state that is contained within a single view and does not influence other parts of your app.

When to use @Bindable instead of using State and StateObject

In cases where a view requires a direct binding to a property of an Observable object within its content, it’s advisable to employ the @Bindable property wrapper. This would typically be declared as @Bindable var model: DataModel within your view. Adopting @Bindable is in line with SwiftUI’s principles for data flow, promoting a more streamlined and robust implementation. This method reduces complications and enhances the integrity of the data interactions within your SwiftUI application

Summary

@State and @StateObject are powerful tools in SwiftUI for state management, tailored for different use cases @State for lightweight, view-local states, and @StateObject for more substantial, persistent data models. By understanding and utilizing these appropriately, you can ensure that your SwiftUI applications are both efficient and easy to manage.

Back To Top