How does LazyVStack choose to re-render if Identifiable is constant?

519 Views Asked by At

How does a LazyVStack in SwiftUI decide if it needs to re-render a View, assuming the Identifiable property of an item it is rendering does not change?

This trivial demo code below, I feel, should not update when the button is clicked, because the Identifiable property of the underlying data set does not change, so no Views should be redrawn and it should use the views it has already cached. However, it seems to work just fine, and I am confused as to why.

enter image description here

struct SomeData: Identifiable {
    var id: Int
    var name: String
}

struct ContentView: View {
    static let dataSetA: [SomeData] = [
        .init(id: 1, name: "One A"),
        .init(id: 2, name: "Two A"),
        .init(id: 3, name: "Three A"),
        .init(id: 4, name: "Four A"),
        .init(id: 5, name: "Five A"),
        .init(id: 6, name: "Six A"),
        .init(id: 7, name: "Seven A"),
        .init(id: 8, name: "Eight A"),
        .init(id: 9, name: "Nine A"),
        .init(id: 10, name: "Ten A")

    ]
    static let dataSetB: [SomeData] = [
        .init(id: 1, name: "One B"),
        .init(id: 2, name: "Two B"),
        .init(id: 3, name: "Three B"),
        .init(id: 4, name: "Four B"),
        .init(id: 5, name: "Five B"),
        .init(id: 6, name: "Six B"),
        .init(id: 7, name: "Seven B"),
        .init(id: 8, name: "Eight B"),
        .init(id: 9, name: "Nine B"),
        .init(id: 10, name: "Ten B")

    ]

    @State var data: [SomeData] = dataSetA

    var body: some View {
        LazyVStack {
            ForEach(data) { datum in
              Text(datum.name)
            }
            Button("Click") {
                data = Self.dataSetB
            }
        }
        .padding()
    }
}
1

There are 1 best solutions below

0
On

Your @State variable is not the individual items, but the array enclosing them – and arrays are also a value type. So when you set data to be a different array, SwiftUI is (correctly) identifying that the view needs to be reassessed.

When it does that reassessment, it doesn't matter that your arrays' constituent items have similar identifiers – the array is different, so the whole list gets re-rendered.