javascriptreact-nativereact-native-flatlist

Flatlist show green tick once an item's API is completed


I am creating a flat list where I need to submit an API with some request options on each item click. After a successful API response, I must show a green tick for that particular flatlist item.

renderItem

const Item = ({item, onPress, backgroundColor, textColor}) => (
  <TouchableOpacity onPress={onPress} style={backgroundColor}>
    <View style={{flexDirection: 'row', width: '100%'}}>
      <Text style={textColor}>{item?.name}</Text>

      <Image
        source={Images.greenTick}
        style={{
          width: 20,
          height: 20,
        }}></Image>
    </View>
  </TouchableOpacity>
);

Here, I am not sure how can I manage the image to be shown in renderItem after API success at a specific index or multiple indexes one by one.


Solution

  • I think you will have to track the clicked item first by maintaining a state. I have tried it in my app once. you can refer to a sample code below

    import React, { useState } from 'react';
    import { View, Text, TouchableOpacity, FlatList, Image } from 'react-native';
    import Images from './Images'; // Assume this is your images import
    
    const MyListComponent = () => {
      const [data, setData] = useState([...]); // your data array
      const [completedItems, setCompletedItems] = useState([]);
    
      const handleItemPress = async (item) => {
        // Call your API here
        try {
          await submitApiCall(item);
          // If API call is successful, add item ID to completedItems state
          setCompletedItems((prevItems) => [...prevItems, item.id]);
        } catch (error) {
          console.error('API call failed:', error);
        }
      };
    
      const renderItem = ({ item }) => (
        <Item
          item={item}
          onPress={() => handleItemPress(item)}
          backgroundColor={{ backgroundColor: '#f9c2ff' }}
          textColor={{ color: 'black' }}
          isCompleted={completedItems.includes(item.id)} // Pass a prop to determine if the item is completed
        />
      );
    
      return (
        <FlatList
          data={data}
          renderItem={renderItem}
          keyExtractor={(item) => item.id.toString()}
        />
      );
    };
    
    const Item = ({ item, onPress, backgroundColor, textColor, isCompleted }) => (
      <TouchableOpacity onPress={onPress} style={[styles.item, backgroundColor]}>
        <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
          <Text style={[styles.title, textColor]}>{item?.name}</Text>
          {isCompleted && <Image source={Images.greenTick} style={{ width: 20, height: 20 }} />}
        </View>
      </TouchableOpacity>
    );
    
    // Add your styles here
    const styles = StyleSheet.create({
      item: {
        padding: 20,
        marginVertical: 8,
        marginHorizontal: 16,
      },
      title: {
        fontSize: 32,
      },
    });
    
    export default MyListComponent;