When toggle Systeme appearance view lost it current state

I'm using initializer for each view. when I pass the store as a parameter, the view behave as expected , but when toggling the system appearance to dark mode the view reinit and store also and it goes back to the initials state .

typealias MyViewListStore = Store<MyViewListState, MyViewListActions>
typealias  MyViewViewStore = ViewStore<MyViewListState, MyViewtListActions>
 struct MyScreen: View {
    // MARK: - Properties
    @ObservedObject var viewStore: MyViewViewStore
    @Environment(\.colorScheme) private var colorScheme
    private var store: MyViewListStore
  
    // MARK: - Initializers
    public init(store: MyViewListStore) {
        self.store = store
        self.viewStore = ViewStore(self.store, removeDuplicates: ==)
    }

    // MARK: - UI Rendering
    var body: some View {
        NavigationView {
            VStack {
            -->  my view content depends on the  view store state values
}

when I initialize the store as a static var it works fine, but I can't use the solution when I need to send some initial data that needs to be passed to the initial state for some other screens

Actual behavior

toggle system appearance -> view store reinit , store states lost and when sending action no state values updates

Hello,
That's probably the sign that you can embed your store in another one that handles the configuration.
With TCA, the single source of truth is the root store. This means that there is no hidden data. If you need to configure a store, you should probably try to model this in terms of TCA.
If this configuration depends on the colorScheme, you need to find a way to bubble this value up to the store. One way to achieve this is to use an .colorScheme(ColorScheme) action that you send at .onAppear and onChange(of:colorScheme). You can then take the appropriate measures in the reducer to configure you content's store. In any case, the root store need to be stored somewhere else than as some view's naked property.

As an aside, removeDuplicates: == is not really required if you store's state is equatable. You will likely need to create a ViewState at some point if this is the root state, but if you're new to TCA, you can probably defer this for some time. You can find more information here.

2 Likes

Hello, thanks for your reply , yes I am new with tca architecture , so here you mean that all store should be scoped within the my AppStore ( root store) ?

In a TCA app, you generally explicitly create only one store, and all other stores are obtained by either scoping it directly, or scoping these scoped stores themselves. There are a few exceptions like document-based apps, but this is usually how it goes. Exceptions apart, there is only one root/app store, and it is static/persistent.

Generally, you should consider (or be able to consider) each store as a complete root store of its own domain. It knows all its children, but it doesn't know if its the root store of the app, or the scoped store of another bigger parent feature it is not aware of. Like in the movie Matrix. Thanks to TCA, you generally don't have to change the internal code of a feature to embed it into a bigger one.

1 Like