Skip to content

Section sticky header in wrong place after list header change until scroll #50189

Open

Description

@Bardiamist

Description

I migrating to the New Architecture.
I have component which worked fine 7 years on the "old architecture".
It uses Animated.SectionList and can hide content in ListHeaderComponent.
In the New architecture on ListHeaderComponent change: section header (renderSectionHeader) goes to the wrong place until manually scroll a little.

Steps to reproduce

  1. Clone and run https://github.com/Bardiamist/diff/tree/section-list-header

  2. Scroll util red header will stick

  3. Press Hide top content after 1 sec button

  4. Wait 1 second
    Expected result: red header should be in same place

  5. Scroll a little

  6. Press Show content after 1 sec button

  7. Wait 1 second
    Expected result: red header should be in same place

React Native Version

0.78.1

Affected Platforms

Runtime - iOS

Areas

Fabric - The New Renderer

Output of npx @react-native-community/cli info

System:
  OS: macOS 15.3.2
  CPU: (10) arm64 Apple M1 Max
  Memory: 11.71 GB / 64.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 23.10.0
    path: /opt/homebrew/bin/node
  Yarn:
    version: 1.22.22
    path: /opt/homebrew/bin/yarn
  npm:
    version: 10.9.2
    path: /opt/homebrew/bin/npm
  Watchman:
    version: 2025.03.10.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.12.1
    path: /usr/local/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.2
      - iOS 18.2
      - macOS 15.2
      - tvOS 18.2
      - visionOS 2.2
      - watchOS 11.2
  Android SDK: Not Found
IDEs:
  Android Studio: 2024.3 AI-243.22562.218.2431.13114758
  Xcode:
    version: 16.2/16C5032a
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.14
    path: /usr/bin/javac
  Ruby:
    version: 2.6.10
    path: /Users/bardiamist/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.0.1
    wanted: 15.0.1
  react:
    installed: 19.0.0
    wanted: 19.0.0
  react-native:
    installed: 0.78.1
    wanted: 0.78.1
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true

Stacktrace or Logs

No crash

Reproducer

https://github.com/Bardiamist/diff/tree/section-list-header

Screenshots and Videos

Works with problem on the New Architecture:

Screen.Recording.2025-03-21.at.13.06.45.mov

Worked as expected on the "old architecture":

Screen.Recording.2025-03-21.at.13.28.19.mov

Activity

  1. cortinico commented on Mar 21, 2025

    @cortinico
    Contributor

    Feels really related to #45229

    Perhaps this is something that @j-piasecki can help us with since he originally sent out the first fix for Animated + sticky header?

  2. j-piasecki commented on Mar 21, 2025

    @j-piasecki
    Contributor

    @cortinico Sure, I can take a look into this.

  3. j-piasecki commented on Apr 14, 2025

    @j-piasecki
    Contributor

    This problem is caused by connectAnimatedNodeToView marking the animated props as needing an update, while the execution of the update happens in didMountComponentsWithRootTag, which runs before the update is requested.

    Enabling the feature flag added in #49908, which causes operations to be flushed after the batch is finished, fixes this.

    Simulator.Screen.Recording.-.iPhone.16.Pro.-.2025-04-14.at.12.02.21.mp4

    cc @cortinico I'm not sure whether this issue should be closed or not, given that the solution is behind a feature flag at the moment.

  4. cortinico commented on Apr 17, 2025

    @cortinico
    Contributor

    Thanks for investigating this @j-piasecki

    cc @cortinico I'm not sure whether this issue should be closed or not, given that the solution is behind a feature flag at the moment.

    @rozele what's the status of this feature flag? When are we planning to enable it?
    If we're planning to enable it in the immediate future, we can close this as fixed as soon as we turn it on

  5. yandadaFreedom commented on May 7, 2025

    @yandadaFreedom

    +1, same problem

  6. rozele commented on May 7, 2025

    @rozele
    Contributor

    We're still in the middle of experimentation with the ReactNativeFeatureFlags.animatedShouldSignalBatch feature flag.

  7. oleksandr-dziuban commented on Jul 30, 2025

    @oleksandr-dziuban

    Seems like a huge blocker for our app to go live with New Architecture :(

    @cortinico do you know when it can be patched? or at least reviewed by RN team?

    Seems like a huge blocker to go PROD with New Arch :

  8. cortinico commented on Jul 30, 2025

    @cortinico
    Contributor

    @rozele is owning this so can provide further updates

  9. rozele commented on Jul 30, 2025

    @rozele
    Contributor

    The animatedShouldSignalBatch flag was removed in #52521. It is being superseded by cxxNativeAnimatedEnabled, but this hasn't been evaluated for open source readiness yet.

  10. oleksandr-dziuban commented on Jul 30, 2025

    @oleksandr-dziuban

    is this animatedShouldSignalBatch affects the sticky header behaviour?

    CC: @rozele

  11. rozele commented on Jul 30, 2025

    @rozele
    Contributor

    is this animatedShouldSignalBatch affects the sticky header behaviour?

    CC: @rozele

    Only in the sense that @j-piasecki mentioned enabling it solved the issue.

  12. gaodeng commented on Dec 15, 2025

    @gaodeng
    Contributor

    any news?

  13. Nezz commented on Oct 21, 2026

    @Nezz

    Still happens on 0.88.0 on iOS, with a plain ScrollView and stickyHeaderIndices: a docked header whose layout changes while the scroll view is idle keeps its old translateY until the next scroll.

    Minimal repro: https://github.com/Nezz/expo-repro/tree/repro/StickyHeader

    Turning on cxxNativeAnimatedEnabled fixes it there, as @j-piasecki found.

    Until that flag is on by default, a JS workaround: set a throwaway native-driven Animated.Value whenever the header's offset node or its translateY changes. That's a flushed operation, so iOS evaluates the new nodes at once (patch). On 0.88, translateY must be among the effect's dependencies, because the header re-renders after the interpolation listener fires and connects a new props node.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue: Author Provided ReproThis issue can be reproduced in Snack or an attached project.Type: New ArchitectureIssues and PRs related to new architecture (Fabric/Turbo Modules)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions