Reputation: 187
I am trying to create a to do list where I remove items and change their status to completed. When I click the checkbox of an item it only deletes the first item, and when I attempt to change the status of the item to completed it says this item does not exist. Therefore, I'm assuming it's an issue with the index of the item I'm passing into the remove function. Any help would be greatly appreciated thank you.
These are the todo objects:
const [todos, setTodos] = useState([
{
text: "Learn about React",
isCompleted: true
},
{
text: "Meet friend for lunch",
isCompleted: false
},
{
text: "Wash Dishes",
isCompleted: false
}
]);
This is what's called when I remove the item
const removeTodo = index => {
const checkTodos = [...todos]; //The list is copied and isCompleted is changed to true
checkTodos[index].isCompleted = true; //This line results in:
setTodos(checkTodos); //Cannot set property 'isCompleted' of undefined
const newTodos = [...todos]; //Here is where I remove from the list
newTodos.splice(index, 1); //I remove the specific index but it deletes only the first
setTodos(newTodos); //item no matter where I click
};
This is how I call the remove function
<div style = {{paddingTop: 40}}>
<List>
{todos.map((value) => {
return(
<ListItem>
<ListItemIcon>
<Checkbox
edge="start"
checked={value.isCompleted}
onChange={removeTodo} //Remove function is called here
tabIndex={-1}
disableRipple
/>
</ListItemIcon>
<ListItemText disableTypography style={{fontFamily: 'Work Sans', fontSize: 35}} primary={value.text}/>
</ListItem>
);
})}
</List>
</div>
Upvotes: 0
Views: 53
Reputation: 4733
In react if you use Map you should give a key to your children so that it could identify all uniquely. Then call the removeTodo with the index to remove it properly.
<div style = {{paddingTop: 40}}>
<List>
{todos.map((value, index) => {
return(
<ListItem key={value}>
<ListItemIcon>
<Checkbox
edge="start"
checked={value.isCompleted}
onChange={() => removeTodo(index)}
tabIndex={-1}
disableRipple
/>
</ListItemIcon>
<ListItemText disableTypography style={{fontFamily: 'Work Sans', fontSize: 35}} primary={value.text}/>
</ListItem>
);
})}
</List>
</div>
Upvotes: 1