[Experiment] "Lazy" forEach
pullbacks and stores
#1227
Replies: 3 comments
-
For some reason, the lazy case is not working well with Previews, so I'm maybe doing something wrong somewhere. It runs fine on a device/simulator, or if I lower the number of Items. |
Beta Was this translation helpful? Give feedback.
-
I've slightly updated the API into something closer to the existing // In the state:
extension Parent {
let lazyItem = LazyIdentifiedArrayConversion(\Self.items) {
`self`, id, item in
item.parentColor = self.color
}
)
}
// In the reducer:
itemReducer.forEachLazy(state: \.lazyItem, action: /ParentAction.item, …)
// In the view:
ForEachLazyStore(
store,
state: \.lazyItem,
action: ParentAction.item,
content: ItemView.init(store:)
) This is slightly less efficient than the previous approach where we directly passed the |
Beta Was this translation helpful? Give feedback.
-
Yeah, this seems like the only efficient way to go about computed collections. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello,
Here is another experiment, this time, around lazy pullbacks/derivations for collections of features.
This aims to solve a performance issue when deriving states from collections.
Using computed properties to pass a common value to an
IdentifiedArray
of features is indeed limited by the size of the array, as a complete array is requested byforEach
pullbacks, even if it's only to update a single element. We can make sure that theIdentifiedArray
is a stored property in good shape at any time, but it requires some careful supervision by a third party reducer to propagate and bake the changes (that could come from very far upstream in the hierarchy), and there are probably models where this is not achievable anyway.In this experiment, I propose a protocol called
LazyCollectionConversion
, and two witnesses:LazyIdentifiedArrayConversion
andLazyDictionaryConversion
where you define how an identified element/value is modified when extracted from the parent. You only need to specify the modifications, as extraction/update of elements of the array/dictionary is automatic.I've updated the case studies with an example that shows the performance difference between a lazy and an eager approach.
If
Item
is a child state with the form:and
Parent
the parent feature with the form:We can define a lazy
Parent/Item
conversion like:In the parent's reducer, you then use:
And in the
ParentView
:That's it!
There are some sharp edges of course. Because this is lazy, you don't have a guarantee over the current values at any time in the collection and you should probably avoid touching them without precautions. I'm working on a larger project that unifies all state derivation into a common pattern, and prevents this kind of issue, but it still needs some work.
The whole feature is gathered into one file and doesn't use internal API's, so you can transplant it easily into your projects it you want to give it a spin.
I'm wondering if this feature alone could be implemented/named in a neater way, or deeper into the library. I'm using "conversion" because of
swift-parsing
, but we could probably use "extraction" or "derivation" for example (albeit I have other works where this term has another meaning).What do you think about it?
Beta Was this translation helpful? Give feedback.
All reactions