'VirtualizedList: You have a large list that is slow to update - make sure your renderItem function renders

Im working on a react-native project and what I'm trying to do is for the user to have the possibility to select phone numbers in his contact list. When the user selects one or more contacts, the app won't work, and it shows this error on the console: VirtualizedList: You have a large list that is slow to update - make sure your renderItem function renders components that follow React performance best practices like PureComponent, shouldComponentUpdate, etc.

ContactList.js

unction ContactList() {
  const [refreshing, setRefreshing] = React.useState(false);
  const [itemChecked, setItemChecked] = useState([]);
  const [checked, setChecked] = useState(new Map());
  const [contacts, setContacts] = useState([]);
  const [filter, setFilter] = useState([]);
  const [search, setSearch] = useState('');
  const [data, setData] = useState(filter)
  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) => {
    checked.set(item, true);
  };

  useEffect(() => {
    checked &&
      setData((previous) => [...previous, {phone: contacts} ])
  }, [checked],
  )

  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' }}>
              <CheckBox
                style={{ width: 15, height: 15 }}
                right={true}
                checked={checked.get(index)}
                onPress={()=> onChangeValue(index)}
              />
            </View>
          </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}
          ListEmptyComponent={<Text message="No contacts found." />}
        />
      </View>
    </SafeAreaView>
  );
}
export default ContactList;

How can I solve this bug?



Sources

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

Source: Stack Overflow

Solution Source