I am having a view with two environment objects. I am displaying data from one of them, and modify data on the other one. When I change the data on the first object, another instance will be created of the second object and its data is cleared.
I created a code example that reproduce the issue, if you run this on preview, and tap on the increment button twice, you will see List is empty!
The list is only loaded on the onAppear
block and this will not be called again when the view is created after the counter update.
struct ContentView: View {
@EnvironmentObject var appState: AppState
var body: some View {
VStack {
View1()
.environmentObject(ListWrapper())
}
}
}
struct View1: View {
@EnvironmentObject var listWrapper: ListWrapper
@EnvironmentObject var appState: AppState
var body: some View {
VStack {
HStack {
Text("Counter:")
Text("\(appState.counter)")
}
HStack {
Button("+") { appState.increment() }.padding(.horizontal, 20)
Divider()
Button("-") { appState.decrement() }.padding(.horizontal, 20)
}.overlay(Rectangle().stroke(Color.accentColor))
.frame(height: 30)
List {
if listWrapper.list.count == 0 {
Text("List is empty!")
} else {
ForEach(listWrapper.list, id:\.self) {
Text($0)
}
}
}
}.onAppear { listWrapper.load() }
}
}
class ListWrapper: ObservableObject {
@Published var list: [String] = []
func load() { list = ["1", "2", "3"] }
}
class AppState: ObservableObject {
@Published var counter: Int = 0
func increment() { counter += 1 }
func decrement() { counter -= 1 }
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(AppState())
}
}
Can someone explain what's the problem and how to fix it?