skip to Main Content

I have my list of todos set up so that a flatList assembles a list of Item components. the Item component is what actually makes the individual Todos. I am trying to make it so that the icon changes when you click the todo to show that it is completed, but the Item component is only loaded when the page refreshes, so despite changing the icon in the state it doesn’t actually change the appearance of the Icon for the user. what I want to know is if I can refresh the flatList so that it updates the icon in the Item component, or if there is a better/easier way to do it.

this is the the part with the flatList:

return (
    <View style={styles.container}>
      <View style={styles.content}>
      <View style={styles.list}>
      <FlatList
        numColumns={1}
        keyExtractor={(item) => item.id}
        data={Assignment}
        renderItem={({ item }) => (
          <Item item={item} pressHandler={pressHandler} />
        )}
          />
    </View>
      </View>
      </View>
  );
}

Assignment is the name of the state.
This is the item component:

return (
      <TouchableOpacity onPress={() => pressHandler(item.id)}>
        <View style={styles.item}>
          <Text style={styles.text}>{item.assignment}</Text>
          <AntDesign name="checkcircleo" size={24} color={item.icon} />
          </View>
       </TouchableOpacity>   
    )

2

Answers


  1. you need to update the assignments everytime you check mark it. here is a basic example of how you should be doing it

    const [assignment, setAssignment] = useState([])
    
    const pressHandler = (id) => {
    
     const newArray = assignment.map(item => {
      if(item.id === id) {
        item.completed = true
      }
      return item
     })
     setAssignment(newArray)
    }
    
    return (
     <TouchableOpacity onPress={() => pressHandler(item.id)}>
      <View style={styles.item}>
        <Text style={styles.text}>{item.assignment}</Text>
        {
          item.checked ?
          <AntDesign name="checkcircleo" size={24} color={item.icon} />
          :
          <AntDesign name="unchecked" size={24} color={item.icon} />
        }
        </View>
     </TouchableOpacity>   
    )
    
    Login or Signup to reply.
  2. You can use this approach

        return (
        <View style={styles.container}>
          <View style={styles.content}>
           <View style={styles.list}>
              <FlatList
                numColumns={1}
                keyExtractor={(item) => item.id}
                data={Assignment}
                extraData={Assignment}
                renderItem={({ item }) => (
                  <Item item={item} pressHandler={pressHandler} />
                )}
              />
            </View>
          </View>
          </View>
      );
    

    For the item rendering

    const Item = (props)=>{
      const {item,pressHandler}=props;
      return (
        <TouchableOpacity onPress={() => pressHandler(item.id,(item.isSelected?false:true))}>
          <View style={styles.item}>
            <Text style={styles.text}>{item.assignment}</Text>
    
            {item.isSelected?<AntDesign name="checkcircleo" size={24} color={item.icon} />:null}
            
            </View>
         </TouchableOpacity>   
      )
    }
    

    onPress handle function and state

    const [Assignment,setAssignment]=useState(ASSIGNMENTS_ARRAY)
    
      const pressHandler = (item,isSelected)=>{
        Assignment.map(assignment=>{
          if(assignment.id!==item.id){
            return {...assignment,isSelected:isSelected}
          }
          return assignment;
        })
    
        setAssignment([...Assignment])
      }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search