0

我正在查看两个环境对象。我正在显示其中一个的数据,并修改另一个上的数据。当我更改第一个对象的数据时,将创建第二个对象的另一个实例并清除其数据。

我创建了一个重现问题的代码示例,如果您在预览中运行它,然后点击增量按钮两次,您将看到列表为空!

该列表仅加载到onAppear块上,并且在计数器更新后创建视图时不会再次调用该列表。

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())
    }
}

有人可以解释问题出在哪里以及如何解决吗?

4

1 回答 1

0

EnvironmentObjects 必须由祖先视图提供!>>> 转到 >>> 窗口组

ContentView()
   .environmentObject(AppState())       // << Here: 1
   .environmentObject(ListWrapper())    // << Here: 2 

    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()
                    listWrapper.list.append(appState.counter.description)        // << Here: 3
                    
                }.padding(.horizontal, 20)
                Divider()
                Button("-") {
                    
                    appState.decrement()
                    listWrapper.list.append(appState.counter.description)        // << Here: 4
                    
                }.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) { item in
                        Text(item)
                    }
                }
 
            }
 
        }.onAppear { listWrapper.load() }
    }
}
于 2021-01-07T20:22:19.443 回答