react-native: Dynamic sticky headers crash natively (Android only)

The FlatList crash natively when updating the stickyHeaderIndices prop. The purpose of my component is to fetch items, and display them inside a flatlist. Some of the loaded items need to be sticky. It’s possible to know which ones only once they are loaded. The problem is that it crashes when stickyHeaderIndices is updated at the same render the new data is added to the flatlist.

See screenshot

Demo: https://snack.expo.io/SkfE8USRN

React Native version:

React Native Environment Info:
    System:
      OS: macOS 10.14.5
      CPU: (4) x64 Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
      Memory: 410.81 MB / 8.00 GB
      Shell: 3.2.57 - /bin/bash
    Binaries:
      Node: 10.13.0 - ~/.nvm/versions/node/v10.13.0/bin/node
      Yarn: 1.16.0 - ~/.nvm/versions/node/v10.13.0/bin/yarn
      npm: 6.9.0 - ~/.nvm/versions/node/v10.13.0/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      iOS SDK:
        Platforms: iOS 12.2, macOS 10.14, tvOS 12.2, watchOS 5.2
      Android SDK:
        API Levels: 23, 25, 26, 27, 28
        Build Tools: 23.0.1, 25.0.2, 26.0.2, 26.0.3, 27.0.0, 27.0.3, 28.0.2, 28.0.3
        System Images: android-23 | Intel x86 Atom_64, android-23 | Google APIs Intel x86 Atom_64, android-27 | Google APIs Intel x86 Atom, android-27 | Google Play Intel x86 Atom
    IDEs:
      Android Studio: 3.4 AI-183.6156.11.34.5522156
      Xcode: 10.2.1/10E1001 - /usr/bin/xcodebuild
    npmPackages:
      react: ^16.8.6 => 16.8.6 
      react-native: ^0.59.8 => 0.59.8 
    npmGlobalPackages:
      react-native-cli: 2.0.1

Steps To Reproduce

  1. Render a flat list with empty data array.
  2. Load your datas (or wait some seconds), and update your array state with the items you loaded.
  3. Compute headers indices for chosen items.

Describe what you expected to happen: No crash.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 19
  • Comments: 39 (2 by maintainers)

Most upvoted comments

I found a temporary workaround for this issue. You can set removeClippedSubviews to false and it should work as intended.

I have the same issue after upgrade to RN 59

Still reproduced

I was trying to debug this and here are my observations:

  1. Issue was only reproducible only on Android phones and with RN version 0.59.*
  2. Tested on iOS with RN 0.59.9 and tested on Android with RN 0.58.* and the ScrollView stickyHeader works fine.
  3. Like @changLiuUNSW noted, any value set to stickyHeaderIndices is causing this crash

Let me take a look into source of RNAndroid to find more on what could have caused it.

please any fix for this aside from setting removeClippedSubviews={false}

this issue has be open 3 years ago and still no fix for it

If you look at ScrollView code… You will see the following

const hasStickyHeaders =
      Array.isArray(stickyHeaderIndices) && stickyHeaderIndices.length > 0;

<ScrollView
 {...otherProps}           
  removeClippedSubviews={
          // Subview clipping causes issues with sticky headers on Android and
          // would be hard to fix properly in a performant way.
          Platform.OS === 'android' && hasStickyHeaders
            ? false
            : this.props.removeClippedSubviews
        }
/>

The problem (as I have observed) is occurring when removeClippedSubviews is determined by dynamic value of hasStickyHeaders, when it is not overridden by the prop set in the component removeClippedSubviews. This is causing the problem in Android.

It is still not working

I just did some research, I believe the stickyHeaderIndices is totally not working for FlatList in Android. You can simply reproduce by creating a FlatList and set stickyHeaderIndices to any value

not sure why this issue get closed, when the issue still exist

I found a temporary workaround for this issue. You can set removeClippedSubviews to false and it should work as intended.

Maaaan Thaanks

@yeswanth I think you pretty much find the cause and can create a PR for them 😃

Strangely, it works when I set removeClippedSubviews to true

still facing same issue

Faced with this.

Temp solution: on Android return loader instead FlatList while items count is zero.

Update: That don’t work when data array is empty. So new workaround for me: render simple view instead of ListEmptyComponent.

@yeswanth Also I just tried set removeClippedSubviews to true, the issue still exists. Have to set it to false