Contents

onChange(of:perform:)

Adds an action to perform when the given value changes.

Declaration

nonisolated func onChange<V>(of value: V, perform action: @escaping (V) -> Void) -> some View where V : Equatable

Discussion

Use this modifier to trigger a side effect when a value changes, like the value associated with an Environment value or a Binding. For example, you can clear a cache when you notice that a scene moves to the background:

struct MyScene: Scene {
    @Environment(\.scenePhase) private var scenePhase
    @StateObject private var cache = DataCache()

    var body: some Scene {
        WindowGroup {
            MyRootView()
        }
        .onChange(of: scenePhase) { newScenePhase in
            if newScenePhase == .background {
                cache.empty()
            }
        }
    }
}

The system may call the action closure on the main actor, so avoid long-running tasks in the closure. If you need to perform such tasks, detach an asynchronous background task:

.onChange(of: scenePhase) { newScenePhase in
    if newScenePhase == .background {
        Task.detached(priority: .background) {
            // ...
        }
    }
}

The system passes the new value into the closure. If you need the old value, capture it in the closure.

See Also

Input and events modifiers