react-native: FlatList doesnot load data after the initialNumToRender count exceeds.

Description

If the initial state of list is empty and it fills in componentDidMount the flatlsit will only render first 10 items from the list of 60. It doenot renders the item after the initialNumToRender count.

React Native Version

0.71.5

Output of npx react-native info

System: OS: macOS 12.6 CPU: (6) x64 Intel® Core™ i5-8500B CPU @ 3.00GHz Memory: 37.58 MB / 8.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 18.13.0 - /usr/local/bin/node Yarn: Not Found npm: 8.19.3 - /usr/local/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman Managers: CocoaPods: 1.11.3 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: DriverKit 22.2, iOS 16.2, macOS 13.1, tvOS 16.1, watchOS 9.1 Android SDK: Not Found IDEs: Android Studio: 4.1 AI-201.8743.12.41.6953283 Xcode: 14.2/14C18 - /usr/bin/xcodebuild Languages: Java: 11.0.17 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 18.2.0 => 18.2.0 react-native: 0.71.1 => 0.71.1 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found

Steps to reproduce

class MyRoomsScreen extends Component {
constructor(){
super()
this.state = {
data: []
}
componentDidMount(){
loadData()
}

loadData(){
let roomArray = []
for(let i =0; i<30;i++){
roomArray.push({id: i+1; name: `Room ${i+1}` })
}
this.setState({data: roomArray})
}

renderRoomList =({item, index}) => {
return(<Text>{item.name} </Text>)
}

render(){
return(
<View>
<FlatList data={this.state.data} renderItem={this.renderRoomList}   />
</View>
)}

Snack, code example, screenshot, or link to a repository

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Reactions: 8
  • Comments: 37 (1 by maintainers)

Most upvoted comments

I am having this same issue and was able to create a snack showing the behavior. Moving the slider or typing in the input field will update the state and cause the FlatList to re-render. Notice that the FlatList sometimes renders only the initialNumToRender and nothing after that.

Expo installs RN 0.70.4 but we initially noticed this when upgrading to RN 0.71.6

Snack: https://snack.expo.dev/wsw-_9se4

Screen Recording showing the behavior: flatlist-behavior

Hi There, I made a fix for this issue. Hope it will help you. The issue is not because of the of the FlatList component, but because InteractionManager.runAfterInteractions() function seems broken for a while already. As there doesn’t seem to be any fix coming soon, I prepared a patch to bypass this function when re-rendering the FlatList cells. As far as I understand, the function is there to wait for the rendering, until the user releases the finger from the screen. With this patch, the re-rendering will be done even if the finger is still touching the screen.

File: node_modules/@react-native/virtualized-lists/Interaction/Batchinator.js Change from this:

  schedule() {
    if (this._taskHandle) {
      return;
    }
    const timeoutHandle = setTimeout(() => {
      this._taskHandle = InteractionManager.runAfterInteractions(() => {
        // Note that we clear the handle before invoking the callback so that if the callback calls
        // schedule again, it will actually schedule another task.
        this._taskHandle = null;
        this._callback();
      });
    }, this._delay);
    this._taskHandle = {cancel: () => clearTimeout(timeoutHandle)};
  }

into this:

schedule(renderWithoutInteractions_patch) {
   if (this._taskHandle) {
     return;
   }
   const timeoutHandle = setTimeout(() => {
           if(renderWithoutInteractions_patch){
                 // Note that we clear the handle before invoking the callback so that if the callback calls
                 // schedule again, it will actually schedule another task.
                 this._taskHandle = null;
                 this._callback();
             }else{
               this._taskHandle = InteractionManager.runAfterInteractions(() => {
                 // Note that we clear the handle before invoking the callback so that if the callback calls
                 // schedule again, it will actually schedule another task.
                 this._taskHandle = null;
                 this._callback();
               });
             }
   }, this._delay);
   this._taskHandle = {cancel: () => clearTimeout(timeoutHandle)};
 }

file: node_modules/@react-native/virtualized-lists/Lists/VirtualizedList.js, Search for the function: _scheduleCellsToRenderUpdate, and change from this:

    } else {
    this._updateCellsToRenderBatcher.schedule();
  }

into this:

     } else {
    this._updateCellsToRenderBatcher.schedule(this.props.renderWithoutInteractions_patch);
 }

file: node_modules/@react-native/virtualized-lists/Lists/VirtualizedList.d.ts Add the prop type and proper docs: Look for the updateCellsBatchingPeriod prop, and add the renderWithoutInteractions_patch prop type after it, together with the comment.

  /**
  * Amount of time between low-pri item render batches, e.g. for rendering items quite a ways off
  * screen. Similar fill rate/responsiveness tradeoff as `maxToRenderPerBatch`.
  */
 updateCellsBatchingPeriod?: number | undefined;

 /**
  * Only use this prop when having re-rendering issuess.
  * This prop will disable the runAfterInteractions inside the .schedule method, inside the Batchinator file.
  * Use this prop carefully :) 
  */
 renderWithoutInteractions_patch?: boolean | undefined;

last change: add the patch prop to your FlatList.

<FlatList
  renderWithoutInteractions_patch <----- Add this prop. Only use it for the FlatLists that have issues
  style={styles.flatlist}
  contentContainerStyle={styles.flatlistContent}
  the rest of your code

finally, you can make a patch for this fix, using patch-package

In my case, I replaced the FlatLists with FlashLists.

I looked for stuck interactions but couldn’t find anything. Maybe some third-party library that we’re using got broken recently, but it’s hard to tell.

@iMonk777 Your patch looks great! Are you planning to create a PR for it to be merged? 😊

No worries @pierroo 😃 I’ve been using the patch for around 6 months now, in three different projects, and I didn’t have any performance issues or any other issues due to the patch(like crashes). The only thing I found strange, when patching it on my latest project, I couldn’t patch it properly until I manually added the dependency in the package.json like so: image It seems that npx patch-package was not happy with patching a peer dependency of react-native, if it was not added to the package.json. I’m not sure though how it worked in the past, for my other two projects ^.^

@jianxinzhoutiti这就是列表在 Rn 中的工作方式,如果您不传递 initialNumberToRender 属性,它将采用默认值 10。并且在 componentDidMount 上的下一个重新渲染中,它将渲染所有列表项。

I just open and close the page,The expectations should show all the data,But a few times it’s only 10 items

之前data长度为0的时候不渲染list,还挺稳定的,最近又不太行了,会频发只渲染10个。 I have fixed this problem with {data?.length>0?<FlatList /> : null}, but recently, it has occurred frequently.

anyone solved this issue it has been 5 months now it seems that the only solution till now is to not send empty data in the initial render to (flatlist/sectionlist) which will break the ListEmptyComponent behaviour

Started running into this after updating to RN 0.72.6, which is the latest version as of today.

Something got broken in FlatLists recently. It’s intermittent, and I’m noticing it mainly in production, not in debug mode. Seems to be more common after resuming the app from background, or after navigation (using react-navigation). iOS 17, iPhone 15 Pro Max, if it matters.