FlatList Component Life Cycle Methods ScrollToIndex ScrollToEnd etc

Johannes Filter picture Johannes Filter · May 8, 2017 · Viewed 9.3k times · Source

I am using the new FlatList component and want to make use of ScrollToIndex (or ScrollToEnd) within lifecycle methods such as componentDidMount.

I have an array of let's say 100 items and I don't want to start to render at the first item but in the beginning. Let's say at the 50th item. When the FlatList is only showing one item at a time, it's working as desired with some hack as described here: https://github.com/facebook/react-native/issues/13202

componentDidMount() {
  let wait = new Promise((resolve) => setTimeout(resolve, 500));  // Smaller number should work
  wait.then( () => {
    this.refs.flatlist.scrollToIndex({index: 4, animated: true});
  });
}

This snippet makes scrollToIndex run after some milliseconds of the invocation of componentDidMount.

But when I use a FlatList where the view comprises a 3x3 grid, I simply cannot make it run. When I use scrollToIndex and the index is outside of the specified props initialNumToRender, I only get an error scrollIndex out of range $ID which I cannot understand. The provided data array has all the, for instance, 100 items. When I make us of scrollToEnd, it only stops somewhere in between and not at the end. For me, it looks like some kind of bug and I don't know any other way how to scroll to the $X item after the initial rendering. Can you help me?

I am grateful for any kind of help or comment.

I tried in on React-Native v0.43.0 and v0.44.0 on iOS and Android (Emulator and Device) and it's always the same.

Answer

Jono picture Jono · Jun 2, 2017

Are you setting a getItemLayout prop on the FlatList?

Check what it says in the React Native code forscrollToIndex - https://github.com/facebook/react-native/blob/master/Libraries/Lists/FlatList.js#L308

This will only really work if your items have a set height though. Seems there isn't a proper solution for items with a variable height yet. I've only managed to get this to work with variable heights by setting initialNumToRender={indexToScrollTo + 1} and then using scrollToOffset instead of scrollToIndex (setting the offset to that of the item you want to scroll to). This has obvious performance issues tho and is really not ideal if you have long lists or your items have complex rendering.