RFC: Require WithViewStore
to specify observed view state
#1340
Replies: 4 comments 11 replies
-
I'm not a native speaker, but I would have rather leaned toward gerunds instead of imperative/infinitive forms: WithViewStore(store, observing: ViewState.init, sending: ViewAction.init) {} I didn't pull the branch to try but I'm wondering if |
Beta Was this translation helpful? Give feedback.
-
We've gone ahead and merged the API as-is, but are open to more feedback before the next release, which will likely be soon, and also with use! |
Beta Was this translation helpful? Give feedback.
-
Looking at this a bit I think making it more ergonomic will make it more acceptable. First, I feel like many users will see Second, this pattern is fairly painful if you only need a single property. Creating a whole type with a custom initializer to extract a single property feels fairly wasteful. I don't have any ideas yet, but some sort of convenience here would help. Third, this optimization is really only relevant for views which are still loaded, right? For instance, if I have a login view that only needs a single property and single action while observing the whole application's state, but the view goes away once the user logs in, there's no harm in observing everything, right? If so this optimization doesn't seem generally applicable. Fourth, it seems that, by defaulting to this behavior, it makes it somewhat harder to refactor screens and flows, as you need to be very particular about the state you prune and changing that state leads to more extensive refactor than it seems like simply accessing an additional property on a screen should. Especially if there are several layers that the state must travel through. So while this may be worthwhile as an optimization point, I'm not sure it makes a good default. Perhaps some guidance around how to figure out you need this optimization might be a good starting point? |
Beta Was this translation helpful? Give feedback.
-
I think it's a good direction, but thinking about the problem of usability while bringing the API in line with other recent updates to TCA, here's a sketch of a different direction. ObserveStore(store, state: \.isVisible) { state, send in
if state.isVisible {
Text("Hello World")
.onAppear { send(.viewAppeared) }
}
} Rationale being:
[Updated] Also drawing inspiration from the ObserveStore(store) // observe the whole store
ObserveStore(store, state: \.someField) // observe a single field
ObserveStore(store, state: ViewState.init) // construct a view state Rationale (3) being fairly separate from the rest but I'd want to rename closure arg anyway? ObserveStore(store) { viewStore in } // confusing: ObserveStore gives me a ViewStore?
ObserveStore(store) { observedStore in } // long and awkward Special consideration for stateless stores? ObserveStore(store.stateless) { send in }
ObservedStore(store, state: ()) { send in } I'm sure this raises plenty of questions and problems, just thought I'd throw the idea out there! |
Beta Was this translation helpful? Give feedback.
-
👋 Hi all!
We just opened #1339 and would love your feedback. It's a big change to a widely-used API, but we think a good one in the long run.
Beta Was this translation helpful? Give feedback.
All reactions