SwiftUI: Text in ChildView does not update in a @ViewBuilder block

In the following playground test, when the button is clicked, the block make is executed and a new value is passed in, why is the @State property text in ChildView always the initial value of 0.


import PlaygroundSupport
import SwiftUI

struct ParentView: View {
    @State var i: Int = 0
    @State var make: (String) -> ChildView

    var body: some View {
        VStack {
            make("\(i)")
            Button {
                i += 1
            } label: {
                Text("CLICK ME")
            }
        }
    }

    init(@ViewBuilder make: @escaping (String) -> ChildView) {
        self.make = make
    }
}

struct ChildView: View {
    @State var text = ""
    var body: some View {
        Text(text)
    }
}

struct ContentView: View {
    var body: some View {
        ParentView { str in
            ChildView(text: str)
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())

Accepted Reply

Hi there,

The @State notation before the text property in ChildView is the reason why. An @State creates a new state while the result you are trying to achieve needs to let the content of the text depends on the parent view. So just remove the @State notation in ChildView and it will work.

You might be interested in these SwiftUI Essentials WWDC videos:

Replies

Hi there,

The @State notation before the text property in ChildView is the reason why. An @State creates a new state while the result you are trying to achieve needs to let the content of the text depends on the parent view. So just remove the @State notation in ChildView and it will work.

You might be interested in these SwiftUI Essentials WWDC videos: