'flatlist slow performance on large data react native

I'm new to react native and I'm having some performance problem with flatlist in React Native Expo. On my screen I'm displaying a list of contacts and I want them to be selected or deselected and I have managed to achieve that part but the problem is that it takes a lot of visibility time to check the contacts or to uncheck them. Making the screen not very user friendly. I have tried a lot of solutions that I've found on internet regarding this problem but none of them had worked. Hope someone can help me. Below I'll attach the code!

function ContactList() {
  const [itemChecked, setItemChecked] = useState([]);
  const [checked, setChecked] = useState(false);
  const [contacts, setContacts] = useState([]);
  const [filter, setFilter] = useState([]);
  const [search, setSearch] = useState('');
  const [checkedBox, setCheckedBox] = useState(false);
  useEffect(() => {
    (async () => {
      const { status } = await Contacts.requestPermissionsAsync();
      if (status === 'granted') {
        const { data } = await Contacts.getContactsAsync({
          fields: [Contacts.Fields.PhoneNumbers],
          // fields: [Contacts.Fields.Name],
        });
        if (data.length > 0) {
          setContacts(data);
          setFilter(data);
          // console.log('contact', contacts[1]);
          // console.log('filter', filter);
        }
      }
    })();
  }, []);

  const searchFilter = (text) => {
    if (text) {
      const newData = contacts.filter((item) => {
        const itemData = item.name ? item.name.toUpperCase() : ''.toUpperCase();

        const textData = text.toUpperCase();
        return itemData.indexOf(textData) > -1;
      });
      setFilter(newData);
      setSearch(text);
    } else {
      setFilter(contacts);
      setSearch(text);
    }
  };

  const onChangeValue = (item, index) => {
    if (itemChecked.includes(item.phoneNumbers[0].digits)) {
      itemChecked.splice(itemChecked.indexOf(item.phoneNumbers[0].digits), 1);
    } else {
      itemChecked.push(item.phoneNumbers[0].digits);
      setCheckedBox(true);
    }

    setItemChecked(itemChecked);
    console.log(itemChecked);
    // console.log(item);
  };

  const renderItem = ({ item, index }) => {
    return (
      <SafeAreaView>
        <ScrollView>
          <TouchableOpacity style={{ flexDirection: 'row', flex: 1 }}>
            <View style={{ flex: 1, borderTopWidth: 0.5, borderTopColor: 'grey', marginBottom: 15 }}>
              <Text onPress={() => setChecked(true)} style={{ fontSize: 20, marginHorizontal: 10 }}>
                {item.name + ' '}
              </Text>
              <Text style={{ fontSize: 17, marginHorizontal: 10, marginTop: 5, color: 'grey' }}>
                {item.phoneNumbers && item.phoneNumbers[0] && item.phoneNumbers[0].number}
              </Text>
            </View>
            <View style={{ flex: 1, borderTopWidth: 0.5, borderTopColor: 'grey' }}>
              {itemChecked.includes(item.phoneNumbers[0].digits) === false ? (
                <CheckBox
                  style={{ width: 15, height: 15 }}
                  right={true}
                  checked={false}
                  onPress={() => {
                    onChangeValue(item, index);
                  }}
                />
              ) : (
                <CheckBox
                  style={{ width: 15, height: 15, paddingTop: 8 }}
                  right={true}
                  checked={true}
                  onPress={() => {
                    onChangeValue(item, index);
                  }}
                />
              )}
            </View>
            {/* <Post postJson={item} isGroupAdmin={isGroupAdmin} user={user} /> */}
          </TouchableOpacity>
        </ScrollView>
      </SafeAreaView>
    );
  };

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.container}>
        <View
          style={{
            height: 40,
            justifyContent: 'center',
            backgroundColor: '#eeeeee',
            width: '90%',
            marginHorizontal: 20,
            marginTop: 15,
            borderRadius: 10,
          }}
        >
          <Feather name="search" size={20} color="grey" style={{ position: 'absolute', left: 32 }} />
          <TextInput
            placeholder="Search"
            placeholderTextColor="#949494"
            style={{
              left: 20,
              paddingHorizontal: 35,
              fontSize: 20,
            }}
            value={search}
            onChangeText={(text) => {
              searchFilter(text);
              setSearch(text);
            }}
          />
        </View>
        <FlatList
          style={{ marginTop: 15 }}
          data={contacts && filter}
          keyExtractor={(item) => `key-${item.id.toString()}`}
          renderItem={renderItem}
          refreshing={true}
          initialNumToRender={10}
          ListEmptyComponent={<Text message="No contacts found." />}
        />
      </View>
    </SafeAreaView>
  );
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
});

export default ContactList;


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source