Empty Data Component of VirtualizedList
Published On: 2024-07-16
Posted By: Harish

When we have list data, we can show using the VirtualizedList component. But what if the data becomes empty?
Generally, we can write a conditional code where we check for data in a list array. If data array length is greater than 0, we show VirtualizedList or show another view component with static no-data text.
As you can see, this process needs extra code and extra conditions. But with the VirtualizedList component, we don't need to write extra conditions. We can use ListEmptyComponent.
We have to pass a view which we want to show on an empty list data and the VirtualizedList component will automatically show this component when the list is empty.
Lets see this in action.
Create A New Project
Create a new react-native project by using npx. Check documentation for creating a new react native project.
npx react-native@latest init VListRN
Example Implementation
We will create a simple colorful vertical VirtualizedList and clear the list on click of a button to show no data found text.
Import and add VirtualizedList
. Add basic VirtualizedList with color blocks. Check basic VirtualizedList implementation for more info.
//App.tsx
...
import { VirtualizedList } from 'react-native';
...
<VirtualizedList
contentContainerStyle={styles.content_container}
data={colors}
getItemCount={getItemCount}
getItem={getItem}
keyExtractor={item => item.id}
renderItem={({ item }) => {
return (
<Item color={item.color} />
)
}}
/>
...
Run the app,
#for Android
npx react-native run-android
#for ios
npx react-native run-ios
Colored blocks list can be seen.
Now we need to show a No Data
text when the list is empty.
For now, pass an empty array to data prop and reload the app.
...
<VirtualizedList
...
data={[]}
/>
...
On load, you will see a blank space. For us, it's blank white space.

Instead of that white space, we want to show a No Data
text at the center of the screen.
In order to do that, we will use the ListEmptyComponent
callback function.
Now create a new empty view component, add a ListEmptyComponent to VirtualizedList and return that newly created empty component in this callback.
...
const EmptyView = () => {
return (
<View style={styles.empty_view}>
<Text style={{ color: 'black' }}>No Data</Text>
</View>
)
};
...
<VirtualizedList
...
data={[]}
ListEmptyComponent={() => <EmptyView />}
/>
...
Now reload the metro builder to see a view with no data message.

For better understanding, we will load the colors list first and on button press, we will make that list empty and show the no data message.
So, use the useState
hook to store the colors array, import and use the Button
component and on button press, update the state with an empty array. You can find the complete code below.
After re-render, you can see the empty data message like in the gif below.

Complete code of our example,
//App.tsx
import React, { useState } from "react";
import {
Text,
StyleSheet,
SafeAreaView,
StatusBar,
View,
VirtualizedList,
Button,
} from "react-native";
const defaultColors = [
'orange',
'green',
'blue',
'maroon',
'violet',
'darkorange',
'gold',
'darkgreen',
'aquamarine',
'cadetblue'
];
type ItemProp = {
color: string;
};
type ItemDataProp = {
id: string;
color: string;
};
export default function App() {
const [colors, setColors] = useState<string[] | []>(defaultColors);
const Item = (props: ItemProp) => {
const { color } = props;
return (
<View
key={color}
style={[
styles.view,
{
backgroundColor: color
}
]}
/>
)
};
const getItem = (data: string[], index: number) => ({
id: Math.random().toString(12).substring(0),
color: data[index],
} as ItemDataProp);
const getItemCount = (data: any) => data.length;
const EmptyView = () => {
return (
<View style={styles.empty_view}>
<Text style={{ fontSize: 20, color: 'black' }}>No Data</Text>
</View>
)
};
return (
<SafeAreaView style={{ flex: 1, backgroundColor: 'white' }}>
<StatusBar
barStyle="dark-content"
/>
<View style={styles.container}>
<Text style={styles.text}>
ifelsething.com
</Text>
<Text style={styles.text}>
empty VirtualiedList
</Text>
<Button
title="Empty List"
onPress={() => setColors([])}
/>
<VirtualizedList
contentContainerStyle={styles.content_container}
data={colors}
extraData={colors}
getItemCount={getItemCount}
getItem={getItem}
keyExtractor={item => item?.id}
ListEmptyComponent={() => <EmptyView />}
renderItem={({ item }) => {
return (
<Item color={item.color} />
)
}}
/>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
margin: 10,
gap: 20
},
text: {
fontSize: 15,
color: 'black',
fontStyle: 'italic'
},
content_container: {
gap: 10,
flexGrow: 1
},
view: {
flexShrink: 1,
width: '100%',
height: 200,
borderRadius: 10,
alignSelf: 'center'
},
empty_view: {
alignItems: 'center',
justifyContent: 'center',
flex: 1,
backgroundColor: 'ghostwhite'
}
});