How to add pagination to a React-Native flatlist

This tutorial will explain how to add pagination to your flatlist while scrolling, so 10 more items get added to the flatlist the more you scroll.

The first thing we need to do as always is create a new React-Native project, use the command below.

react-native init paginationflatlist

After we have created the project we need to open this in our favourite code editor, mine is VS code.

The firs thing we need to do is open the “App.js” file and change the “App” class to be the below.

class App extends React.Component {constructor(props) {super(props);this.state = {loading: true,randomUserData: [],loadingExtraData: false,page:1}}render() {return (<View></View>)}}

The class includes a constructor that will contain a state object.

The state object contains a “loading” key which will be the value of an activity indicator that loads on load of the component. A “randomUserData” array which will contain the flatlist data, and a “loadingExtraData” boolean that will be the value of another activity indicator for when we load extra data. In addition, we have a state value for the page of the flatlist so we can monitor whether we are only loading the first 10 results or the next 10.

After you have copied this we need to import the “FlatList” and “TouchableOpacity” components from React-Native so now our import will look like the below.

import React from 'react';import {SafeAreaView,StyleSheet,ScrollView,View,Text,StatusBar,FlatList,TouchableOpacity} from 'react-native';

We now need to create a method named “LoadRandomData” and use fetch to retrieve data from our random data api. The url we will be retrieving from is “”, so the max number of results we can get at a time is 10.


We will now use a promise to access the response and then convert the response to json using “response.json”


We then will access this json data through another “then” and set our state value “randomUserData” depending on what the “page” value is, because if it is one then we only want to load the first page retrieved from the API, however, if “page” is greater than 1 then we want to concatenate the current state array with the array of the latest results retrieved from the API, so our data from page 1 will concatenate with page 2, giving it the pagination functionality, the 3 dots “…” are also known as the spread operator.

fetch(`${}`).then(response=>response.json()).then(responseJson=>{this.setState({randomUserData: === 1 ? responseJson.results : [...this.state.randomUserData, ...responseJson.results]})})

We will also add a “catch” so we can see any errors that are returned in the console.

LoadRandomData = () => {fetch(`${}`).then(response => response.json()).then(responseJson => {this.setState({randomUserData: === 1 ? responseJson.results : [...this.state.randomUserData, ...responseJson.results]})}).catch(error => {console.log('Error selecting random data: ' + error)})}

The next thing we need to do is add a “FlatList” component and set its data property equal to “this.state.randomUserData”. Also we need to run our “LoadRandomData” on the “componentDidMount” lifecycle method so the data from the API shows on the flatlist on the load of the component.

<View style={{ marginTop: 50 }}><FlatListdata={this.state.randomUserData}style={{ width: 350, height: 800 }}/></View>

So now our “flatlist” has a container and style properties too.

Below is how our “componentDidMount” lifecycle method currently looks.

componentDidMount() {this.LoadRandomData()}

Our next step is to determine how we want our data on the “Flatlist” to show using the in built method “renderItem”.

Make a method named “renderCustomItem” which has 2 parameters and are destructured, the parameter names must be “item” and “index”.

We will be returning the gender, name and image from the API. So copy the code below to do this within the “renderCustomItem” method.

renderCustomItem = ({ item, index }) => {return (<View style={{justifyContent:'center',alignItems:'center'}}><Text>{item.gender}</Text><Text>{["first"]} {["last"]}</Text><Image source={{ uri: item.picture["medium"] }} style={{width:200,height:200}} /></View>)}

“name” is a key of another object hence why we have to traverse it the way we do. I should have said this earlier but you now must import the “Image” component from “react-native” so now our “import” statement from react-native looks like the below.

import {SafeAreaView,StyleSheet,ScrollView,View,Text,StatusBar,FlatList,TouchableOpacity,Image} from 'react-native';

We set the “Source” property equal to the “medium” object key of “picture” from the API. The “uri” is there to represent the url as a resource identifier.

So now that we have created the custom item method we set the in built method “renderItem” to


After you have done all of this run the command below for the iOS simulator.

react-native run-ios

You should see something like the below.

We now need to create a method that will contain the keyExtractor. A key extractor tells the flat list to use a specified id/key instead of the default key property.

We will set ours to the users email address, so create a method called “keyExtractor” with 2 parameters “item” and “index” and set the value to “” like below.

keyExtractor = (item,index) =>;

So now our flat list looks like the below.

<FlatListdata={this.state.randomUserData}renderItem={this.renderCustomItem}style={{ width: 350, height: 800 }}keyExtractor={this.keyExtractor}/>

We now need to create a method that will handle the loading of the next 10 records on the flatlist we will call this method “LoadMoreRandomData”.

All we need to do in this method is increment the state value of “page” by 1, and use the callback of set state to run the “LoadRandomData” method. We increment the page value because in our fetch request we set a query parameter called “page” equal to the state value “page” so by default the state value “page” is 1, so the first page of the first 10 results is loaded, then when we get to the bottom of the flatlist the next 10 results are loaded.(I will explain how react-native knows you are at the bottom in a second)

“onEndChanged” is a built in method on the flatlist and for our project that runs the “LoadMoreRandomData” method, increments the “page” state value by 1 so it would be 2, and retrieves the second page of the API data because the query param “page” in the “fetch” request url is set to the “page” state value, then in the “LoadRandomData” it then does a check if the state value “page” is 1 then just retrieve the first set of results, else if it is not 1 then concatenate the new set of retrieved data with the original set of data.

After adding those changes the flatlist will look the below.

LoadMoreRandomData = () =>{this.setState({},()=>this.LoadRandomData())}

For react-native to know you are at the bottom or near the bottom of the flatlist there are 2 methods to know about, these are “onEndReachedThreshold” and “onEndReached”.

OnEndReachedThreshold is a numeric value which runs the “onEndReached” method depending on how far from the end the bottom edge of the list has to be from the end of the content to run the method “onEndReached”. If you were to set the value to 0.5 “onEndReached” will run when the content is half way visible length of the list, however, for now lets just set it to 0 so we have to be at the bottom of the list to reload the data.

So now our flatlist looks like the below.

<FlatListdata={this.state.randomUserData}renderItem={this.renderCustomItem}style={{ width: 350, height: 800 }}keyExtractor={this.keyExtractor}onEndReachedThreshold={0}onEndReached={this.LoadMoreRandomData}/>

If you run the simulator again you should a working flatlist and when you scroll down to the bottom another 10 results from the API should appear.

We could add more customization to this including a loading indicator and footer component, however, I just wanted to keep it simple for this tutorial.

Hopefully you learned something from this tutorial, if I can improve on anything please let me know and I will try to incorporate those changes in my next tutorial.

Check out my blog —




Software Developer in the UK. With a keen passion for React Native & C#

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Developing custom dropdowns with vanilla JS & CSS (In under 5 minutes)

A Guide to React Before You Start Coding


Setting up Universal Web locally

Building a User Registration and Login with VUE and Firebase Auth

Components Javascript

Build a NodeJS cinema booking microservice and deploying it with docker (part 3)

Understanding Generators in ES6 JavaScript

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store


Software Developer in the UK. With a keen passion for React Native & C#

More from Medium

MVVM Pattern In React

Dynamic fields in a form using react.js | react-native | add/delete input fields

Dynamic Fields in a form using react.js | react-native

What is the difference between ReactJS and React Native | Made with React JS