@Observable is being re-init every time view is modified

I am surprised at what I am seeing with the new @Observable framework in iOS 17.

It seems that if the view containing the @State var, ie viewModel, is modified, then the init of that viewModel will also be called. This is not the behavior of the prior StateObject method of using a viewModel.

As I understand the @State should not be reinitialized on redrawing on the View, is this the expected behavior?

Example:

struct ContentView: View {

@State var offset = false

var body: some View {
    VStack {
        InnerView()
            .offset(x: offset ? 200 : 0)
            
        Button("Offset") {
            offset.toggle()
        }
    }
}

}

// iOS 17 Observable method:

struct InnerView: View {

@State var viewModel: ViewModel

init() {
    self._viewModel = State(wrappedValue: ViewModel())
}

var body: some View {
    VStack {
        Image(systemName: "globe")
            .imageScale(.large)
            .foregroundStyle(.tint)
        Text("Hello, world!")
    }
    .padding()
}

}

@Observable class ViewModel {

init() {
    print("ViewModel Init")
}

}

// StateObject method:

struct InnerView: View {

@StateObject var viewModel: ViewModel

init() {
    self._viewModel = StateObject(wrappedValue: ViewModel())
}

var body: some View {
    VStack {
        Image(systemName: "globe")
            .imageScale(.large)
            .foregroundStyle(.tint)
        Text("Hello, world!")
    }
    .padding()
}

}

class ViewModel: ObservableObject {

init() {
    print("ViewModel Init")
}

}

Post not yet marked as solved Up vote post of Ches Beiner Down vote post of Ches Beiner
632 views

Replies

I'm facing exact same problem.

Same problem. Would love to know the right way to implement this pattern with @observable