I have a very simple codes and I want keep it as much as possible simple, I am using a ForEach to render some simple Text, for understanding what is happening undercover I made a TextView to get notified each time this View get called by SwiftUI, unfortunately each time I add new element to my array, SwiftUI is going to render all array elements from begging to end, which I want and expecting it call TextView just for new element, So there is a way to defining an array of View/Text which would solve the issue, but that is over kill for such a simple work, I mean me and you would defiantly use ForEach in our projects, and we could use a simple Text inside ForEach or any other custom View, how we could solve this issue to stop SwiftUI initializing same thing again and again, whith this in mind that I want just use a simple String array and not going to crazy and defining a View array.
My Goal is using an simple array of String to this work without being worry to re-initializing issue.
Maybe it is time to re-think about using ForEach in your App!
SwiftUI would fall to re-rendering trap even with updating an element of the array! which is funny. so make yourself ready if you got 50 or 100 or 1000 rows and you are just updating 1 single row, swiftUI would re render the all entire your array, it does not matter you are using simple Text or your CustomView. So I would wish SwiftUI would be smart to not rendering all array again, and just making necessary render in case.
import SwiftUI
struct ContentView: View {
@State private var arrayOfString: [String] = [String]()
var body: some View {
ForEach(arrayOfString.indices, id:\.self) { index in
TextView(stringOfText: arrayOfString[index])
}
Spacer()
Button("append new element") {
arrayOfString.append(Int.random(in: 1...1000).description)
}
.padding(.bottom)
Button("update first element") {
if arrayOfString.count > 0 {
arrayOfString[0] = "updated!"
}
}
.padding(.bottom)
}
}
struct TextView: View {
let stringOfText: String
init(stringOfText: String) {
self.stringOfText = stringOfText
print("initializing TextView for:", stringOfText)
}
var body: some View {
Text(stringOfText)
}
}