Sachu
Sachu

Reputation: 187

Issue removing item from list

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

Answers (1)

moshfiqrony
moshfiqrony

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

Related Questions