react-native: Large Flatlist is not rendering all items

Is this a bug report?

This seems to be a bug of the FlatList while trying to render many items (more that 60-70).

Have you read the Contributing Guidelines?

(Write your answer here.)

Environment

We are using macOS and the issue happen on both iphone and android

  1. react-native -v: 0.45.1
  2. node -v: 6.9.1
  3. npm -v: 3.10.8
  4. yarn --version:

Then, specify:

  • Target Platform: iOS, Android
  • Development Operating System: macOS
  • Build tools: Xcode, Android Studio

Steps to Reproduce

We are using FlatList to render Message Items and after the Flatlist has been rendered we are using scrollToBottom to go to the last item. The Flatlist is working without any issues when having about 20 items, but when we have many items it is NOT always rendering them and not display them at all. We are having an example with 80 items and sometimes is rendering all of them but most of the times is rendering about 40.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 14
  • Comments: 45 (3 by maintainers)

Most upvoted comments

For partial shown short list: added those values to FlatList and problem gone:

<FlatList style={{ flex: 0 }}
                    initialNumToRender={data.length}

honestly i don’t know which one fixes the problem or if works for large data.

I solved the issue by removing flex style property from the container of renderItem. Perhaps this is worth reporting as a separate issue linked specifically with the problematic flex behavior 🤔

You just need to add attribute initialNumToRender in your Flatlist. Example:

<Flatlist
    data={array}
    initialNumToRender={array.length}
    renderItem={({ item }) => <ListItem item={item} />}
/>

We had this issue of FlatList not rendering some of the items, even after scrolling some of the items were just not rendered. Only some external state change managed to cause the FlatList to render (often just partially).

After a lot of digging, I found out that a long-running animation was causing this issue. Animations seem to cause FlatList to delay item rendering by default, so we managed to fix this by adding a parameter isInteraction: false to the ongoing animation:

Animated.timing(this.controlValue, {
    to: someValue,
    useNativeDriver: true,
    isInteraction: false,
}).start()

After this, FlatList no longer waited for the animation to finish, and was rendering everything as expected.

Note, that basically any animation within your app can cause this, not just the ones within FlatList.

I solved my problem: Never mutate or map over your props for list items. Simple maps or copies of the props will not work properly- you have to do all your logic in redux or before changing props and use data={this.props.data}.

remove getItemLayout property settings works for me

Hi, I’m running react-native v0.52.8 and I have the same issue. Will this be fixed? or we have to use third party components?

I am having a similar issue, but not even on large lists, sometimes it just only renders partial rows, and the rest of the data are all just blank which you can clearly see that the list left some blank space for the rest of the data, but just not rendering them. This just happens sometimes, most of time it works perfect, very hard for me to find out where excatly went wrong.

I have the issue where only the initial buffer is rendered and no other items (left blank when scrolling). Can confirm it has something to do with getItemLayout in my case, but can’t remove it as it’s needed to scroll to index. {flex: 0} does not solve it.

What is strange is that it works in a storybook (minimal use case) but not inside the app (maybe react-navigation related?). Also in my case the <FlatList /> is inside a <Modal />

Only workaround so far is initialNumToRender={1000}… Not great!

edit: Another thing that fixes it is to add debug={true} prop on the <FlatList/>, not sure if it helps.

Looking at the code it looks like the culprit might be this line in Libraries/Lists/VirtualizedList.js:

const onLayout =
      /* $FlowFixMe(>=0.68.0 site=react_native_fb) This comment suppresses an
       * error found when Flow v0.68 was deployed. To see the error delete this
       * comment and run Flow. */
      getItemLayout && !parentProps.debug && !fillRateHelper.enabled()
        ? undefined
        : this.props.onLayout;

Not sure what it is supposed to optimize away…

edit : Can confirm that bypassing this ternary (eg. const onLayout = this.props.onLayout fixes it for me. Maybe I should open another issue?

@RWOverdijk this worked, thanks.

I was having the same issue with long lists on ios. I have list items that can display more items on a button click. The flatlist would grow the the correct length/height, but would stop rendering at either 10 or 15 items, and only display a blank white area for the rest of the list. Switching ios over to ListView fixed the display issue.

No issues on android with FlatList.

We have the same issue on android and have to revert to ListView.

It does seem to render, the jumping of next batch being rendered is visible but at some point it just cuts off. The space is reserved but nothing is visible. In fact, inspecting it (react views) shows the space. Everything is in the tree, it just doesn’t show (or shows transparent).

Note: When making the items considerably smaller (20 height) the entire list does render. So it looks like there’s some sort of cut-off point.

@satellink I think your suggestion (setting useInteraction: false) on animations may have solved this for me. 🤞

From the RN docs on https://facebook.github.io/react-native/docs/animated#loop: “In addition, loops can prevent VirtualizedList-based components from rendering more rows while the animation is running. You can pass isInteraction: false in the child animation config to fix this.”

Sorry to say, but I didn’t find any solution working for me. I’m still facing the same issue.

I’ve noticed that I get this problem, and it goes away when I stop remotely debugging the app…

Quite what is going on to cause such a difference in the performance of this element between debug and non-debug mode where other elements seem to have no issue, I’m not sure.

I wonder if it’s related to time differences between host and emulated system - see #4470. My time differs by about a second between host and emulator, and setTimeout’s with small delays, and setImmediate’s seem to take a about second to trigger. (My Android emulator’s time matches my Android phone, but my Mac’s time is about a second ahead, both are set to use ‘network’ time… go figure…)

My situation: using RN 55.4, whilst debugging the app, FlatList will render the initial items on load, (I had 4 items rendered by default) but will not load ‘subsequent’ items until ‘many seconds’ later. I have just disabled/stopped remote debugging, and it seems to load the extra elements ‘immediately’. Setting removeClippedSubviews to false had no effect. Setting initialNumToRender={data.length} resulted in all the items rendered, but the scrollable area went beyond the end of the list until the ‘render the rest of the items’ code actually ran (and found there to be no more items to render). As far as I can see, there’s no flex definition relating to my item’s rendering…

I decided to use ScrollView and rendering the list of items and header by myself, I know that this can have some performance problems but it works for me now.

<ScrollView >
<MyHeaderComponent/>         
          {
            items.map((item) => {
               return <MyRowComponent  item={item}/>
             })
           }
</ScrollView>