React Native’s SectionList and getItemLayout

Jan Söndermann
3 min readJun 26, 2017

--

The new SectionList in action!

New: See what’s in your AsyncStorage by logging it to your console from the dev menu.

The React Native team recently added a bunch of new list components to replace the old ListView, including a dedicated SectionList component. Like FlatList, its simpler cousin, SectionList takes a getItemLayout prop that you can use to tell it about the dimensions of the stuff on your list.

When you start playing around with the new list components, you’ll soon realize that adding this prop is pretty important, primarily for two reasons:

  1. Without getItemLayout, your list can’t know how long it will be until you get to the last row. This means your scroll bar will start out huge and jump back to the middle as the list loads additional content. This is annoying especially for lists that don’t dynamically load content when you get to the bottom because you have all the information you need to make the scroll bar accurate from the start.
  2. More importantly, if your rows are slow to render, the list won’t let you scroll past the last currently rendered row which makes for an extremely frustrating user experience. If, however, you tell your list how tall each row will be, you can freely scroll up and down the list. Unrendered rows will show up as blank, which still isn’t great, but it’s much better than not letting your user scroll at all.

getItemLayout is a function that is given two parameters: data, which is the data shown on your list (it’s the same as the data prop you pass into your list) and index, the index of the row for the row in question. It’s supposed to return an object with three props: offset, the distance from the top of the first row to the top of the row at index index; length, which is the height of your row and index, which is simply the index parameter passed into the function.

For FlatList, this function is relatively simple to write. If all of your rows are of the same height, you can simply return {offset: ROW_HEIGHT * index, length: ROW_HEIGHT, index}. If they aren’t or if you have separators between your rows, it gets slightly more complicated but it’s still obvious what you should return.

In the case of SectionList, it’s less clear how to compute the correct result. As for FlatList, you get given an index parameter, which, according to my experiments and the source, flattens all section headers and rows into one list and points at the object with index in that list. This means if you have two sections with three rows each, an index of 1 would refer to the first row while an index of 4 points at the second section header.

After going through the trouble of figuring this out, I extracted the code that I wrote into a function that takes your section header height, the height of your separators and a function that returns the height of a given row and returns a getItemLayout function that you can feed into your SectionList. It’s available as react-native-section-list-get-item-layout on npm and github and used like this:

--

--