Scroll up and bounce back loop issue when wrapping LazyVstack within a NavigationStack

The issue I'm facing arise when using a lazyvstack within a navigationstack. I want to use the pinnedViews: .sectionHeaders feature from the lazyStack to display a section header while rendering the content with a scrollview. Below is the code i'm using and at the end I share a sample of the loop issue:

struct SProjectsScreen: View {
    @Bindable var store: StoreOf<ProjectsFeature>
    
    @State private var searchText: String = ""
    @Binding var isBotTabBarHidden: Bool
    
    @Environment(\.safeArea) private var safeArea: EdgeInsets
    @Environment(\.screenSize) private var screenSize: CGSize
    @Environment(\.dismiss) var dismiss
    
    private var isLoading : Bool {
        store.projects.isEmpty
    }
    
    var body: some View {
        NavigationStack(path:$store.navigationPath.sending(\.setNavigationPath)) {
            ScrollView(.vertical){
                LazyVStack(spacing:16,pinnedViews: .sectionHeaders) {
                    Section {
                        VStack(spacing:16) {
                            if isLoading {
                                ForEach(0..<5,id:\.self) { _ in
                                    ProjectItemSkeleton()
                                }
                            }
                            else{
                                ForEach(store.projects,id:\._id) { projectItem in
                                    NavigationLink(value: projectItem) {
                                        SProjectItem(project: projectItem)
                                            .foregroundStyle(Color.theme.foreground)
                                    }
                                    .simultaneousGesture(TapGesture().onEnded({ _ in
                                        store.send(.setCurrentProjectSelected(projectItem.name))
                                    }))
                                }
                            }
                        }
                    } header: {
                        VStack(spacing:16) {
                            HStack {
                                Text("Your")
                                Text("Projects")
                                    .fontWeight(.bold)
                                Text("Are Here!")
                                
                            }
                            .font(.title)
                            .frame(maxWidth: .infinity,alignment: .leading)
                            .padding(.horizontal,12)
                            .padding(.vertical,0)
                            
                            HStack {
                                SSearchField(searchValue: $searchText)
                                
                                Button {
                                    
                                } label: {
                                    Image(systemName: "slider.horizontal.3")
                                        .foregroundStyle(.white)
                                        .fontWeight(.medium)
                                        .font(.system(size: 24))
                                        .frame(width:50.66,height: 50.66)
                                        .background {
                                            Circle().fill(Color.theme.primary)
                                        }
                                }
                            }
                        }
                        .padding(.top,8)
                        .padding(.bottom,16)
                        .background(content: {
                            Color.white
                        })
                    }
                }
            }
            .scrollIndicators(.hidden)
            .navigationDestination(for: Project.self) { project in
                SFoldersScreen(project:project,isBotTabBarHidden: $isBotTabBarHidden)
                .toolbar(.hidden)
            }
            .padding(.horizontal,SScreenSize.hPadding)
            .onAppear {
                Task {
                    if isLoading{
                        do {
                            let projectsData = try await ProjectService.Shared.getProjects()
                            store.send(.setProjects(projectsData))
                        }
                        catch{
                            print("error found: ",error.localizedDescription)
                        }
                    }
                    
                }
        }
            .refreshable {
                do {
                    let projectsData = try await ProjectService.Shared.getProjects()
                    store.send(.setProjects(projectsData))
                }
                catch{
                    print("error found: ",error.localizedDescription)
                }
            }
        }.onChange(of: store.navigationPath, { a, b in
            print("Navigation path changed:", b)
        })

    }
}

I'm using tca library for managing states so this is my project feature reducer:

import ComposableArchitecture
@Reducer
struct ProjectsFeature{
    
    @ObservableState
    struct State: Equatable{
        var navigationPath : [Project] = []
        var projects : [Project] = [
        ]
        var currentProjectSelected : String?
    }
    enum Action{
        case setNavigationPath([Project])
        case setProjects([Project])
        case setCurrentProjectSelected(String?)
        case popNavigation
    }
    
    var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
                case .setNavigationPath(let navigationPath):
                    state.navigationPath = navigationPath
                    return .none
                case .setProjects(let projects):
                    state.projects = projects
                    return .none
                case .setCurrentProjectSelected(let projectName):
                    state.currentProjectSelected = projectName
                    return .none
                case .popNavigation:
                    if !state.navigationPath.isEmpty {
                        state.navigationPath.removeLast()
                    }
                    state.currentProjectSelected = nil
                    return .none
            }
        }
    }

I can't completely reproduce the issue because of the 3rd party library dependency. However I would first suggest you don’t use if/else control flow for your loading state. You’re breaking the structural identity of the View. Demystify SwiftUI WWDC session covers of structural identity.

Instead you could use redacted(reason:) or ContentUnavailableView for cases where a view’s content cannot be displayed.

For example:

struct ContentView: View {
    private let items = (1...50).map { "Item \($0)" }
    
    @State private var isLoading = true
    
    var body: some View {
        ScrollView {
            LazyVStack(spacing: 12) {
                ForEach(items, id: \.self) { item in
                    Text(item)
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .padding()
                        .background(Color(.systemBackground))
                        .cornerRadius(8)
                        .shadow(color: Color.black.opacity(0.1), radius: 2, x: 0, y: 1)
                }
            }
            .padding()
        }
        .redacted(reason: isLoading ? .placeholder : [])
        .refreshable {
            isLoading = true
            try? await Task.sleep(for: .seconds(1))
            isLoading = false
        }
        .task {
            try? await Task.sleep(for: .seconds(2))
            isLoading = false
        }
    }
}
Scroll up and bounce back loop issue when wrapping LazyVstack within a NavigationStack
 
 
Q