Created
September 25, 2023 20:02
-
-
Save markmals/2d4a3f2a294b9638f0137eb8a4825f88 to your computer and use it in GitHub Desktop.
Fine-grained @observable interactions vs coarse-grained decoding
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// With Observable | |
@Observable | |
class Book { | |
var title: String | |
var author: String | |
var inStock: Bool | |
init(title: String, author: String, inStock: Bool) { | |
self.title = title | |
self.author = author | |
self.inStock = inStock | |
} | |
} | |
struct Parent: View { | |
@State var book: Book | |
var body: some View { | |
MyView(book: book) | |
.onAppear { | |
// Will not cause an update to MyView | |
book.author = "Me" | |
} | |
} | |
} | |
struct MyView: View { | |
let book: Book | |
var body: some View { | |
// Only updates when book.title changes | |
// Doesn't update when book.author or book.inStock change | |
Text(book.title) | |
} | |
} | |
// With @State | |
class Book { | |
var title: String | |
var author: String | |
var inStock: Bool | |
init(title: String, author: String, inStock: Bool) { | |
self.title = title | |
self.author = author | |
self.inStock = inStock | |
} | |
} | |
struct Parent: View { | |
@State var book: Book | |
var body: some View { | |
MyView(book: book) | |
.onAppear { | |
// Will cause an update to MyView | |
book.author = "Me" | |
} | |
} | |
} | |
struct MyView: View { | |
let book: Book | |
var body: some View { | |
// Updates any time `book` or any of its properties changes | |
Text(book.title) | |
} | |
} | |
// With @Observable and Decodable | |
@Observable | |
class Book: Decodable { | |
var title: String | |
var author: String | |
var inStock: Bool | |
init(title: String, author: String, inStock: Bool) { | |
self.title = title | |
self.author = author | |
self.inStock = inStock | |
} | |
} | |
struct Parent: View { | |
@State var book: Book | |
var body: some View { | |
MyView(book: book) | |
.task { | |
// You're only ever replacing the entire book | |
book = await fetchBook() | |
} | |
} | |
func fetchBook() async -> Book {...} | |
} | |
struct MyView: View { | |
let book: Book | |
var body: some View { | |
// Updates any time the whole book is fetched | |
Text(book.title) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment