@chris @shadowfacts @kyle echoing the above, I think this is made more explicit if you use the State init, like _vm = State(initialValue: …)
This makes it more obvious why the initial example was broken and avoids a new vm on every init (but you still need your onchange)
@shadowfacts @chris @kyle woof -- here's to hoping there's some magical new tool that eliminates all this confusion.
IME it’s far too easy to just not realize you're accidentally recreating state 60 times/sec because you modeled it incorrectly.
@shadowfacts @kyle I updated the article to show a variant that doesn't always recreate the VM. It's tricky.
BTW, @shadowfacts I really enjoyed reading your article about preferences!
@chris thanks for the article!
How should one go about creating StateObjects in view’s init? Should one avoid init(wrappedValue:) ?
@chris ah thanks for this. we go back and forth on how we should be managing this on our team a lot. an article to point to from a member of the community like you is super helpful, fwiw.
lots of follow up questions i could ask, but i’ll limit to just this one for now: are there effects to making bare view properties like `name` vars instead of lets?
i’ve always made those lets, but i don’t really have a good reason to i guess, and now i’m wondering if i’m doing something bad after seeing you use vars.
@chris The way I've been handling it (in small hobby apps, take with grain of salt) is to *always* put view models in the environment. In line with your article's advice, this has the advantage that it ensures state is updated in a body function.
Relevant to a discussion I was having with @orj recently, SwiftUI thrives on very few view models so using the environment makes sense (better drives a deep tree of views or passing through utility layout views).
@mamouneyya @chris @orj Environment values are not globals. The environment is a scoped context – so it exists only in the subtree where you apply it.
This means you can apply a separate environment value for every row in a list, and they will not interfere with each other.
@chris Thanks for the article Chris. You clearly lay out the pitfalls here in some common patterns and how SwiftUI is working.
However I’d argue that issue being showcased by the chosen example indicates that the source of truth is being created / held at the wrong level.