SwiftUI prevent onReceive from firing on load

2.1k views Asked by At

Is there any way to prevent onReceive from firing when the view initially loads when the variable I'm trying to receive is a @Published property of an @EnvironmentObject?

Here's the view:

struct ContentView: View {
    @EnvironmentObject var appState: AppState
    
    var body: some View {
        VStack {
            Text(appState.test)
                .padding()
        }
        .onAppear() {
            appState.test = "World"
        }
        .onReceive(appState.$test) { test in
            print("Hello from onReceive: \(test)")
        }
    }
}

Here's the environment object:

public class AppState: ObservableObject {
    @Published public var test = "hello"
}

And output:

Hello from onReceive: hello
Hello from onReceive: World

I'm guessing the first one is fired when the environment object is injected. Is there any way to prevent this (other than some hackish bool that I set in the onAppear)? Ideally I'd like to only see "Hello from onReceive: World" This is just a simple example. On my actual app I am fetching data from a service in onAppear, in my environment object I have an error state that when cleared, I want it to fire the onReceive do some other logic then refetch.

1

There are 1 answers

0
Asperi On

It is publisher, so you can use any combine operators. In this case .dropFirst solves your task:

    .onReceive(appState.$test.dropFirst()) { test in
        print("Hello from onReceive: \(test)")
    }