ForEachStore has empty state?

I try to build a cascade of views that show a list of sections, a list of cards within each section, and a list of items within a cards.
The topmost view shall load some data when .onAppear is triggered. Those data are loaded in a viewReducer, that sets a state.mainSections property. Each State conforms to Identifiable and Equatable.

However, when the ForEachStore statement in the view is performed, and when examining the state $0 content, it only shows empty content, i.e.: the state modification does not appear there.

Am I doing something wrong, or is this a kind of bug?

The essential code for the store:

struct MainOverview {
	private init() {}
	
	struct Environment {		
		var maintainableDataProvider: MaintainableDataProvider
	}
	
	struct State: Equatable, Identifiable {
		
		init() {}
		var id: UUID = .init()
		var dataGroups: [MaintainableDataGroup] = []
		var mainSections: IdentifiedArrayOf<MainSection.State> = []

		static func ==(lhs: State, rhs: State) -> Bool {
			
			return lhs.id == rhs.id &&
				lhs.dataGroups == rhs.dataGroups &&
				lhs.mainSections == rhs.mainSections
		}
	}
	
	enum Action {
		enum ViewAction {
			case onAppear
			case onDisappear
		}
		
		case viewAction(ViewAction)
		case mainSections(UUID, MainSection.Action)
	}
	
	static let reducer = Reducer<State, Action, Environment>
		.combine(

			MainSection.reducer.forEach(
				state: \State.mainSections,
				action: /Action.mainSections,
				environment: {
					MainSection.Environment(
						maintainableDataProvider: $0.maintainableDataProvider
					)
				}
			),

			viewReducer.pullback(
				state: \.self,
				action: /Action.viewAction,
				environment: { $0 }),
			
			generalReducer
		)
	
	static let generalReducer = Reducer<State, Action, Environment> { state, action, env in
		
		switch action {
			
			case let .viewAction(_):
				return .none
				
			case let .mainSections(uuid, action):
				return .none
		}
	}
	
	static let viewReducer = Reducer<State, Action.ViewAction, Environment> { state, action, env in
		
		switch action {
			
			case  .onAppear:
				debugPrint("Appearing: MainOverview")
				let result = env.maintainableDataProvider.dataGroups

				switch result {
					case let .success(dataGroups):
						state.mainSections = IdentifiedArrayOf(
							dataGroups.map({ dataGroup in
								
								MainSection.State(
									dataGroup: dataGroup
								)
							})
						)
// Should enforce the state update, but has no effect for ForEachStore:
						state.id = UUID()
						return .none
						
					case .failure:
						return .none
				}
				
			case .onDisappear:
				return .none
		}
	}
}

The essential code for the view:

let store: Store<MainOverview.State, MainOverview.Action>
	
    var body: some View {
		
		WithViewStore(store) { viewStore in
			
			VStack {
				
				ScrollView(.vertical) {

					ForEachStore(
						self.store.scope(
							state: { // This is empty:
								debugPrint(">>>", $0) 
								return $0.mainSections
							},
							action: MainOverview.Action.mainSections
						)
					) { childStore in

						MainSectionView(store: childStore)
					}
					.debug("MainOverviewView ForEachStore")
				}
			}
			.debug("MainOverviewView redrawing")
			.onAppear {
				viewStore.send(.viewAction(.onAppear))
			}
			.onDisappear {
				viewStore.send(.viewAction(.onDisappear))
			}
		}
		.debug()
	}

The debug output:

>>> MainOverview.State(id: 45DCC4F4-EE49-4CF9-89F2-75AB5335BA36, dataGroups: [], mainSections: [])
>>>MainOverview.State(id: 45DCC4F4-EE49-4CF9-89F2-75AB5335BA36, dataGroups: [], mainSections: [])
Terms of Service

Privacy Policy

Cookie Policy