Home > OS >  editing object inside array use setState react native
editing object inside array use setState react native

Time:12-13

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>   
    )

CodePudding user response:

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>   
)

CodePudding user response:

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])
  }
  • Related