React Native. Filter FlatList - error "index=10 count 0"

Viewed 2570

My task is to filter some array and set it to FlatList.

My filter function is:

updateInvoiceList = (text) => {
  let invoiceList = [...this.state.baseInvoiceList];
    invoiceList = invoiceList.filter(el => {
     return el.name.toLowerCase().includes(text.toLowerCase())
    });
  this.setState({invoiceList})
}

After filtering, I provide state.invoiceList to FlatList and everything works correctly. But, when I set some symbol which does not exist in my array, for example "!", the function clears the array and it still behaves correctly. When I remove the symbol "!", I get an error screen with:

 index=10 count=0
addInArray
    ViewGroup.java:5235
addViewInner
    ViewGroup.java:5128
addView
    ViewGroup.java:4935
addView
    ReactViewGroup.java:452
addView
    ViewGroup.java:4875
addView
    ReactViewManager.java:269
addView
    ReactViewManager.java:36
manageChildren
    NativeViewHierarchyManager.java:346
execute
    UIViewOperationQueue.java:227
run
    UIViewOperationQueue.java:917
flushPendingBatches
    UIViewOperationQueue.java:1025
access$2600
    UIViewOperationQueue.java:46
doFrameGuarded
    UIViewOperationQueue.java:1085
doFrame
    GuardedFrameCallback.java:29
doFrame
    ReactChoreographer.java:166
doFrame
    ChoreographerCompat.java:84
run
    Choreographer.java:964
doCallbacks
    Choreographer.java:790
doFrame
    Choreographer.java:721
run
    Choreographer.java:951
handleCallback
    Handler.java:883
dispatchMessage
    Handler.java:100
loop
    Looper.java:214
main
    ActivityThread.java:7356
invoke
    Method.java
run
    RuntimeInit.java:492
main
    ZygoteInit.java:930

What did I do wrong?

5 Answers

I had the exact same issue with my code, inside a Flatlist and only showing up on Android. I've managed to solve it as follows:

My FlatList had

stickyHeaderIndices={this.state.items[1]}

but apparently the List was loading that stickyHeader ahead of its initialization. From here, the solution consists simply in handling the case in which that item is not initialized yet.

stickyHeaderIndices={this.state.items.length > 0 ? [1] : [0]}

Hope this helps! The solution is pretty straightforward. Debugging it can be a real pain, tho!

On Android, you must not initialise your FlatList stickyHeaderIndices with empty array.

Instead, when your state is not loaded yet, provide FlatList data with some initial data and provide stickyHeaderIndices with [0]

Example code as below

let [data, stickyIndices] = someAPIToGetYourData()
...
...
...
// if your data is not finished loading yet
if (data.length === 0) {
  // create not-empty array
  data = getInitialNotEmptyData()
  // add not-empty index
  headerIndexList = [0]
}

return (
  <SafeAreaView>
    <FlatList
      data={data}
      stickyHeaderIndices={headerIndexList /* This must not be empty */ }
      renderItem={item => renderYourItem(item)}
    />
  </SafeAreaView>
)

Hope this help!

I needed kill the FlatList to fix this error, like this:

    <View>  
      { this.state.data.length > 0 &&   
        <FlatList
          showsVerticalScrollIndicator={false}
          refreshing={false}
          onRefresh={() => this.onRefresh()}
          data={this.state.data}
          extraData={this.state}>}
    </View>

Hope this helps!

LayoutAnimation causes a similar issue, not only with Flatlist but any kind of lists, check if you are using it in your app and if you have UIManager.setLayoutAnimationEnabledExperimental(true) on your top component, removing it might fix your issue, but will disable the layoutAnimations.

You might find more information here and here

Please improve your function.

updateInvoiceList = (text) => {
  let invoiceList = [];
  const { baseInvoiceList } =  this.state;
  if(text){
     invoiceList = baseInvoiceList.filter(item => {
       return item.name.toLowerCase().includes(text.toLowerCase());
     });
 }
 this.setState({invoiceList});
}
Related