Build an image browsing App with React Native (4) — RecyclerListView

Kai Xie
Geek Culture
Published in
3 min readJun 7, 2021

React Native brings React’s declarative UI framework to iOS and Android. With React Native, you use native UI controls and have full access to the native platform. (https://github.com/facebook/react-native)

And this is the 4th article of this tutorial about how to build an image browsing App with React Native. So I suppose you have read the prior parts of it.

There are the links to these prior chapters.

Actually, we have implemented all features of such an image browsing app, including displaying images in a FlatList, fetching data from backend API, saving data in persistent storage, save data in a global state store with Redux, navigating from one route to another route with react-navigation. So in this article, I would just have some improvements like using RecyclerListView to display the images instead of using FlatList.

What is RecyclerListView?It is a high-performance listview for React Native and Web with support for complex layouts. JS only with no native dependencies, inspired by both RecyclerView on Android and UICollectionView on iOS.

RecyclerListView uses “cell recycling” to reuse views that are no longer visible to render items instead of creating new view objects. The creation of objects is very expensive and comes with a memory overhead which means as you scroll through the list the memory footprint keeps going up. Releasing invisible items off memory is another technique but that leads to the creation of even more objects and a lot of garbage collections. Recycling is the best way to render infinite lists that do not compromise performance or memory efficiency.

https://github.com/Flipkart/recyclerlistview

It would be able to do all things the FlatList can do, but with better performance.

Add RecyclerListView package

Firstly we need to add a new package to support RecyclerListView by running

yarn add recyclerlistview

and you would find a new dependency is added to the Package.json in your project.

Create RecyclserList component

Then let’s create a new file, RecyclerList.tsx in the home folder, and add the following code

import React from 'react';
import {
RecyclerListView,
DataProvider,
LayoutProvider,
Dimension,
} from 'recyclerlistview';
import {StyleSheet, StatusBar, Dimensions} from 'react-native';
import Item from './Item';
const getWindowWidth = () =>
Math.round(Dimensions.get('window').width * 1000) / 1000 - 6;
const RecyclerList = ({
data,
nextPage,
navigation,
}: {
data: Array<Photo>;
nextPage: () => void;
navigation: any;
}): JSX.Element => {
console.log(
'RecyclerList',
data.map(item => item.id),
);
const renderItem = (type: string | number, data: any) => (
<Item photo={data} navigation={navigation} />
);
const dataProvider = new DataProvider((r1, r2) => {
return r1 !== r2;
}).cloneWithRows(data);
const layoutProvider = new LayoutProvider(
index => {
return JSON.stringify({
width: data[index].width,
height: data[index].height,
});
},
(type: string | number, dim: Dimension) => {
switch (type) {
case 'VSEL':
dim.width = getWindowWidth() / 2;
dim.height = 150;
break;
default:
if (typeof type === 'string') {
const {width, height} = JSON.parse(type);
dim.width = getWindowWidth() / 2;
dim.height = 250;
}
}
},
);
return (
<RecyclerListView
style={styles.container}
dataProvider={dataProvider}
layoutProvider={layoutProvider}
rowRenderer={renderItem}
onEndReached={nextPage}
/>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: StatusBar.currentHeight || 0,
marginHorizontal: 0,
},
});
export default RecyclerList;

Then we implemented a component, RecyclerList with RecyclerListView. And we can render the image list with this new component. We would replace the original List component on the Home component later.

Actually, most of the codes are standard. What we need to do is implementing our own DataProvider, with which the array of images are consumed, and LayoutProvider, with which we can customize the layout. But there is still some limitation, for instance, the RecyclerListView doesn’t support dynamic height for each element, so we are unable to render the elements with masonry list.

Update the Home component

And then the last step is to update the following line in the Home component

import List from './List';

with

import {default as List} from './RecyclerList';

And then run the app again. But you would find nothing changed because it is just a performance enhancement to use RecyclerListView instead of FlatList. Nothing changed for the user.

Ok. This chapter is a short and simple one. And thanks for reading it.

--

--