Replies: 2 comments 7 replies
-
By the way, I've tested with nested |
Beta Was this translation helpful? Give feedback.
1 reply
-
Would something like this work? And a corresponding public init<SomeState, OtherState, OtherAction>(
_ store: Store<SomeState, Action>,
combiningStateFrom otherStore: Store<OtherState, OtherAction>,
removeDuplicates isDuplicate: @escaping (State, State) -> Bool
_ combine: @escaping (SomeState, OtherState) -> State,
) {
self._send = { store.send($0) }
self._state = CurrentValueRelay(combine(store.state.value, otherStore.state.value))
self.viewCancellable = store.state.combineLatest(otherStore.state, combine)
.removeDuplicates(by: isDuplicate)
.sink { [weak objectWillChange = self.objectWillChange, weak _state = self._state] in
guard let objectWillChange = objectWillChange, let _state = _state else { return }
objectWillChange.send()
_state.value = $0
}
} Then I'd be able to do this: let viewStore_ = ViewStore(store, combiningStateFrom: seenWordsStore, removeDuplicates: ==) { (cardState, seenState) in
cardState.viewState(with: seenState)
} |
Beta Was this translation helpful? Give feedback.
6 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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, I have been trying to solve this conundrum for several days now, but can't find a good solution.
Short version
The short version is that I have two
Stores
and I want to create a store that takes state from both, given a transform function that combines the states. For my purposes it is fine to ignore the actions from the second store. I have a suggestion for a function that does this in a later post.Full version
My situation is that I have
Pages
in aTabView
Cards
in aVStack
Card
I have a number ofWords
To make this nice I have a
MainState
with anlet pages: IdentifiedArrayOf<Page>
property. In eachPage
I have anIdentifiedArrayOf<Card>
etcI have two levels of
ForEachStore
, and this all works pretty well, except I get some excessive rendering of invisiblePages
, and for some reason I can't make theVStack
lazy. But this is not the issue now. Instead it's this:Word
is derived both from the metadata in eachIconState
, inside the the array of arrays inMainState
, and from a propertylet seenWords: Set<Word.ID>
onMainState
.The way I see it there are three options:
1. Pre-combine
seenWords
andpages
already inMainState
, and then feed into theForEachStores
.Now this would be simple to use, there would be a computed property "pageViewStates" that automatically was kept updated, but this would involve re-calculating the entire list of lists so that each
Word
gets a properlet seen: Bool
value, even when just a single value was added toseenWords
. It would probably be computed a lot more than that, considering how SwiftUI works.2. Manually update the
seen
property on the affected words whenseenWords
orpages
changesThis is efficient, since we only flip the state, and only on the relevant words. We don't touch all the other metadata in each
Word
, and especially not on theCards
andPages
. On the other hand it gets very messy (in reality it's more complex than justseenWords
, there are at least three different inputs, and theseen
state actually has five different values). It also seems to go against the idea of SwiftUI and reactive paradigms.3. Apply the
seenWords
list on eachWord
, and the leaf so to speak.This is what seems most appealing to me. We can do this in a straightforward way on each word, for example a function:
We don't care how often this function gets called since it would only happen on visible
Words
. In fact I wouldn't mind doing it at theCard
level either, that shouldn't be an issue.The problem is that I can't get the
Card
to render whenSeenWords
changes in this scenario.This doesn't trigger a re-render (or even init) when
seenWordsStore
changes. It doesn't help to move the state out of the init, and extract it in the "superview":I'm thinking that what I want is something like
Beta Was this translation helpful? Give feedback.
All reactions