I would like help to further understand the implications of using the following 2 methods for driving data between multiple views.
My situation: A parent view initialises multiple child views with data passed in.
- This data is a big object.
- Each view takes a different slice of the data.
- Each view can manipulate the initial data (filtering, ordering etc)
Using an observableObeject to store this data and multiple published properties for each view :
- can be passed in as an environment object that can be accessed by any view using @EnvironmentObject.
- You can create a Binding to the published properties and change them.
- Execute a method on the ObservableObject class and manipulate a property value which gets published using
objectWillChange.send()
inside the method.
I have achieved the desired listed above by using a struct with mutating
methods. Once these properties are changed in the struct, the views which bind to these properties causes a re-render.
My struct does not do any async work. It sets initial values. Its properties are modified upon user action like clicking filter buttons.
Example
struct MyStruct {
var prop1 = "hello"
var prop2: [String] = []
init(prop2: [String]) {
self.prop2 = prop2
}
mutating func changeProp2(multiplier: Int) {
let computation = ...
prop2 = computation //<----- This mutates prop2 and so my view Binded to this value gets re-renderd.
}
}
struct ParentView: View {
var initValue: [String] // <- passed in from ContentView
@State private var myStruct: MyStruct
init(initValue: [String]) {
self.myStruct = MyStruct(prop2: initValue)
}
var body: some View {
VStack {
SiblingOne(myStruct: $myStruct)
SiblingTwo(myStruct: $myStruct)
}
}
}
struct SiblingOne: View {
@Binding var myStruct: MyStruct
var body: some View {
HStack{
Button {
myStruct.changeProp2(multiplier: 10)
} label: {
Text("Mutate Prop 2")
}
}
}
}
struct SiblingTwo: View {
@Binding var myStruct: MyStruct
var body: some View {
ForEach(Array(myStruct.prop2.enumerated()), id: \.offset) { idx, val in
Text(val)
}
}
}
Question:
What use cases are there for using an ObservableObject than using a struct that mutates its own properties?
There are overlap use cases however I wish to understand the differences where:
- Some situation A favours ObservableObject
- Some situation B favours struct mutating properties