React Native Basics: Implementing Infinite Scroll

Written by mulev | Published 2020/07/04
Tech Story Tags: react | react-native | software-engineering | programming | javascript | tutorial | software | mobile

TLDR In this short tutorial, Mike Mulev gives a step-by-step guide on how to implement one of React Native's most powerful features: infinite scroll. The goal is to implement an infinite scroll. One of the easiest ways is to display a long list of simple elements and make them properly scrollable. We will go with a simple array of elements right in the app code: [ { id : 1, text : 'One', { { id: 'One' } ] [ { data = 'Data', { color color: 'Drow', { height : 10, width : 0, height : 0.5, margin : 3, bottom: 3,Bottom, margin: 3.5'via the TL;DR App

React Native is without any doubt a strong and powerful solution. It opens the world of cross-platform app development for a much wider audience of software engineers who aren’t familiar with native technologies. But it might at the same time be quite difficult to implement complex things when you’ve just started learning. In this short tutorial, I want to give a step-by-step guide on how to implement one of them — infinite scroll.

The Preparation

Ok, so let’s begin. For the purposes of this short tutorial, I’ll use the Expo library — it’s quite handy when it comes to building simple React Native applications. So, make sure the following is installed on your machine:
  • Node.js — I’d just go with the latest stable version. To manage Node versions I prefer nvm
  • Expo.io — install it following their official installation guide
First of all, open the console and create a basic minimal app using the expo executable: 
expo init infinite_scroll
. It offers to choose a template from which the application will be created — just go with the blank option, that’s enough to achieve our today’s goal.
Now we need to wait a tiny bit while 
expo
 is preparing our app and installing all the underlying libraries. Once it’s done we have a fully functional React Native application that we can launch by calling 
expo start
.
Expo offers a very handy option — to run your application in the iOS simulator. That’s how our app looks like when we launch it for the first time:

The Promising Start

Now we’re all set for development — let’s write some code. Open the app directory in your favorite code editor and find there in the root a file named 
App.js
App.js
 is the entry point of the application, and that’s how it looks like at the very beginning:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
Our goal is to implement an infinite scroll. One of the easiest ways is to display a long list of simple elements and make them properly scrollable. Further in development, you could connect your app to a data source, like an external API, or a local data storage, but we will go with a simple array of elements right in the app code:
const data = [
  {id: 1, text: 'One'}
]
The second thing we should define is how we will display each of the elements. Since we are working with React Native, we have all the powers of React at our service, so we need to define a new view, that will represent a single element. For that, we’ll define a new 
const Item
 and use the functional approach to return a 
<View>
 component with a 
<Text> 
component inside:
const Item = ({item}) => {
  return (
    <View>
      <Text>{item.text}</Text>
    </View>
  );
}
Those are all just standard React Native components, so you don’t need to connect any third-party libraries to your project.
It’s also a good idea to style our element a bit to make it look nicer, for example as a white rectangle with a shadow so it’ll look like it’s levitating on top of the background.
Here’s the final code with the styling applied:
...
const data = [
  {id: 1, text: 'One'}
]

const Item = ({item}) => {
  return (
    <View style={[styles.item, styles.shadow]}>
      <Text>{item.text}</Text>
    </View>
  );
}
...
const styles = StyleSheet.create({
  item: {
    backgroundColor: '#fff',
    padding: 20,
    marginHorizontal: 10,
    marginBottom: 3.5,
    flexDirection: 'row'
  },
  shadow: {
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 10
    },
    shadowOpacity: 0.47,
    shadowRadius: 9,
  }
});
After that, we’re almost all set to see the first list element gently floating over the background of our iOS Simulator. And the last thing due is actually the core thing to make our list infinitely scrollable — the 
<FlatList> 
component. You can find more about it in the official documentation.
On a short note, it takes three basic input arguments to do its job:
  • data
    , where the data source should be passed. In our case, it’s a constant with the same name that we’ve defined on an earlier step;
  • renderItem
    , to which we pass the defined earlier 
    Item
     constant and which makes sure to render each of the 
    data
    ;
  • keyExtractor
     that is responsible for finding unique keys in your data set — they’re required for proper rendering of elements.
  • ...
    const List = () => {
      return (
        <FlatList
          contentContainerStyle={styles.list}
          data={data}
          renderItem={Item}
          keyExtractor={item => item.id}
        />
      );
    }
    
    export default function App() {
      return (
        <List />
      );
    }
    
    const styles = StyleSheet.create({
      list: {
        paddingVertical: 30,
        justifyContent: 'flex-start'
      }
    });
After applying those changes to the App.js, we can see first satisfying and encouraging results in the Simulator:

The Mighty Eighteen

Now that we have everything in place for multiple list elements, let’s just add them — The Mighty Eighteen items that will take all the Simulator screen and even more. And that’s exactly what we need to test our implementation of the infinite scroll.
const data = [
  {id: '1', text: 'One'},
  {id: '2', text: 'Two'},
  {id: '3', text: 'Three'},
  {id: '4', text: 'Four'},
  {id: '5', text: 'Five'},
  {id: '6', text: 'Six'},
  {id: '7', text: 'Seven'},
  {id: '8', text: 'Eight'},
  {id: '9', text: 'Nine'},
  {id: '10', text: 'Ten'},
  {id: '11', text: 'Eleven'},
  {id: '12', text: 'Twelve'},
  {id: '13', text: 'Thirteen'},
  {id: '14', text: 'Fourteen'},
  {id: '15', text: 'Fifteen'},
  {id: '16', text: 'Sixteen'},
  {id: '17', text: 'Seventeen'},
  {id: '18', text: 'Eighteen'},
]
The last thing that will wrap it all up is the 
<SafeAreaView>
 React Native component that ensures its enclosed content will not conflict with any other components around it. Please see more in the official documentation.
Here’s the final state of the 
App.js
:
import React from 'react';
import { StyleSheet, Text, View, FlatList, SafeAreaView } from 'react-native';

const data = [
  {id: '1', text: 'One'},
  {id: '2', text: 'Two'},
  {id: '3', text: 'Three'},
  {id: '4', text: 'Four'},
  {id: '5', text: 'Five'},
  {id: '6', text: 'Six'},
  {id: '7', text: 'Seven'},
  {id: '8', text: 'Eight'},
  {id: '9', text: 'Nine'},
  {id: '10', text: 'Ten'},
  {id: '11', text: 'Eleven'},
  {id: '12', text: 'Twelve'},
  {id: '13', text: 'Thirteen'},
  {id: '14', text: 'Fourteen'},
  {id: '15', text: 'Fifteen'},
  {id: '16', text: 'Sixteen'},
  {id: '17', text: 'Seventeen'},
  {id: '18', text: 'Eighteen'},
]

const Item = ({item}) => {
  return (
    <View style={[styles.item, styles.shadow]}>
      <Text>{item.text}</Text>
    </View>
  );
}

const List = () => {
  return (
    <FlatList
      contentContainerStyle={styles.list}
      data={data}
      renderItem={Item}
      keyExtractor={item => item.id}
    />
  );
}

export default function App() {
  return (
    <SafeAreaView style={styles.container}>
      <List />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    justifyContent: 'center',
  },
  list: {
    paddingVertical: 30,
    justifyContent: 'flex-start'
  },
  item: {
    backgroundColor: '#fff',
    padding: 20,
    marginHorizontal: 10,
    marginBottom: 3.5,
    flexDirection: 'row'
  },
  shadow: {
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 10
    },
    shadowOpacity: 0.47,
    shadowRadius: 9,
  }
});
And that’s how the scrolled down feed in the app looks like:
In the next tutorial, we'll add a button floating on top of our items list and make that button adding even more items to the list.

Written by mulev | 8+ years in software engineering
Published by HackerNoon on 2020/07/04