pointfreeco / swift-composable-architecture

A library for building applications in a consistent and understandable way, with composition, testing, and ergonomics in mind.
https://www.pointfree.co/collections/composable-architecture
MIT License
12.61k stars 1.46k forks source link

View randomly doesn't update iOS 17 #2851

Closed arnauddorgans closed 9 months ago

arnauddorgans commented 9 months ago

Description

I have a ScrollView containing a LazyVStack with four views, each with its scope. Randomly, one of the views is not updated. When I add a tap gesture on the not updated view to print the state, the state prints correctly updated, but the update is not visible in the view.

    let store: StoreOf<DiscoverCategory>

    var body: some View {
        ScrollView { _ in
            WithPerceptionTracking {
                if store.hasError {
                    // Error sate placeholder
                } else if store.isEmpty {
                    // Empty sate placeholder
                } else {
                    content
                }
            }
            .padding(.vertical, Spacing.medium)
        }
    }

@MainActor
    private var content: some View {
        WithPerceptionTracking {
            LazyVStack(spacing: Spacing.huge) {
                // One of the following view is randomly not updated
                if store.showSubcategorySection {
                    SubcategoryListSectionView(store: store.scope(
                        state: \.subcategoryListSection,
                        action: \.subcategoryListSection
                    ))
                }
                ShowListSectionView(store: store.scope(
                    state: \.showListSection,
                    action: \.showListSection
                ))
                ProductListSectionView(store: store.scope(
                    state: \.productListSection,
                    action: \.productListSection
                ))
                ShowListGridSectionView(store: store.scope(
                    state: \.showList,
                    action: \.showList
                ))
            }
        }
    }

I have no runtime warning or nothing.

Checklist

Expected behavior

No response

Actual behavior

No response

Steps to reproduce

No response

The Composable Architecture version information

1.8.2

Destination operating system

iOS 17

Xcode version information

Xcode 15.2

Swift Compiler version information

swift-driver version: 1.87.3 Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
Target: arm64-apple-macosx14.0
stephencelis commented 9 months ago

@arnauddorgans WithPerceptionTracking needs to be used wherever a "lazy"/@escaping closure is, which LazyVStack is. Try moving the WithPerceptionTracking into the lazy view:

 @MainActor
 private var content: some View {
-  WithPerceptionTracking {
   LazyVStack(spacing: Spacing.huge) {
+    WithPerceptionTracking {

Because this isn't a bug in the library I'm going to convert to a discussion.