@State 属性 不会按预期更改其值,直到我添加 `onChange(of:)` 函数

@State Property Doesn't Change Its Value as Expected, until I add `onChange(of:)` Function

import SwiftUI

struct ContentView: View {
    @State private var openSheet = false
    @State private var foo = 0
    
    var body: some View {
        Button {
            setFoo(100)
            openSheet = true
        } label: {
            Text("Open Sheet")
        }
        .padding()
        .frame(width: 400, height: 300, alignment: .center)
        .sheet(isPresented: $openSheet) {
            Text(String(foo))
                .padding()
                .frame(width: 200, height: 150, alignment: .center)
        }
    }
    
    private func setFoo(_ foo:Int) {
        self.foo = foo
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

当上面的代码 运行 时,结果是“0”而不是“100”。但是,如果我添加“.onChange(of:)”函数,结果变为“100”。

import SwiftUI

struct ContentView: View {
    @State private var openSheet = false
    @State private var foo = 0
    
    var body: some View {
        Button {
            setFoo(100)
            openSheet = true
        } label: {
            Text("Open Sheet")
        }
        .padding()
        .frame(width: 400, height: 300, alignment: .center)
        .sheet(isPresented: $openSheet) {
            Text(String(foo))
                .padding()
                .frame(width: 200, height: 150, alignment: .center)
        }
        .onChange(of: openSheet) { newValue in
        }
    }
    
    private func setFoo(_ foo:Int) {
        self.foo = foo
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

知道为什么会这样吗?

使用此处的众多@Asperi 答案之一: Sheet inside ForEach doesn't loop over items SwiftUI

你可以使用这样的东西:

extension Int: Identifiable {
    public var id: Int { self }
}

struct ContentView: View {
    @State private var foo: Int?  // <-- here
    
    var body: some View {
        Button { setFoo(100) } label: { Text("Open Sheet") }
            .padding()
            .frame(width: 400, height: 300, alignment: .center)
            .sheet(item: $foo) { newFoo in    // <-- here
                Text(String(newFoo))
                    .padding()
                    .frame(width: 200, height: 150, alignment: .center)
            }
    }
    
    private func setFoo(_ foo:Int) {
        self.foo = foo
    }
}