ifelsething logoifelsething

Empty Data Component of VirtualizedList

Published On: 2024-07-16
Posted By: Harish

empty list data message in virtualizedlist

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.

blank space in virtualizedlist when data is empty

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.

no data message when list is empty

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.

empty data message when VirtualizedList is empty

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'
  }
});

Share is Caring

Related Posts