visit
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
.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',
},
});
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>
);
}
...
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 .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'
}
});
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 .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,
}
});
Previously published at