0

I was going through the React docs and was attempting to modify a TodoList Item. https://codesandbox.io/s/43njy6458x

I am trying to remove each component with a button, however the button does not delete the item. I have tried a few methods to filter the list, yet none have successfully accomplished the function.

    const ToDo = props => (
  <tr>
    <td>
      <label>{props.id}</label>
    </td>
    <td>
      <input />
    </td>
    <td>
      <label>{props.createdAt.toTimeString()}</label>
      <button
        type="button"
        onClick={props.deleteItem}
        value={props.id}
      >
        Delete
      </button>
    </td>
  </tr>
);

class ToDoList extends React.Component {
  constructor() {
    super();
    const date = new Date();
    const toDoCounter = 1;
    this.state = {
      list: [
        {
          id: toDoCounter,
          createdAt: date,
        },
      ],
      toDoCounter: toDoCounter,
    };
  }

  sortByEarliest() {
    const sortedList = this.state.list.sort((a, b) => {
      return a.createdAt - b.createdAt;
    });
    this.setState({
      list: [...sortedList],
    });
  }

  sortByLatest() {
    const sortedList = this.state.list.sort((a, b) => {
      return b.createdAt - a.createdAt;
    });
    this.setState({
      list: [...sortedList],
    });
  }

  addToEnd() {
    const date = new Date();
    const nextId = this.state.toDoCounter + 1;
    const newList = [
      ...this.state.list,
      {id: nextId, createdAt: date},
    ];
    this.setState({
      list: newList,
      toDoCounter: nextId,
    });
  }

  addToStart() {
    const date = new Date();
    const nextId = this.state.toDoCounter + 1;
    const newList = [
      {id: nextId, createdAt: date},
      ...this.state.list,
    ];
    this.setState({
      list: newList,
      toDoCounter: nextId,
    });
  }
// this is the issue
  deleteItem(event) {

    const clickedId = event.target.value;
    //console.log(clickedId);
    const arrDes = [...this.state.list];
    const newList = this.state.list.filter((item) => {

    //console.log(item.id);
    return item.id !== clickedId;
    })
    this.setState({
      list: newList
    });
  }

  render() {
    return (
      <div>
        <code>key=id index=id</code>
        <br />
        <button onClick={this.addToStart.bind(this)}>
          Add New to Start
        </button>
        <button onClick={this.addToEnd.bind(this)}>
          Add New to End
        </button>
        <button onClick={this.sortByEarliest.bind(this)}>
          Sort by Earliest
        </button>
        <button onClick={this.sortByLatest.bind(this)}>
          Sort by Latest
        </button>
        <table>
          <tr>
            <th>ID</th>
            <th />
            <th>created at</th>
          </tr>
          {this.state.list.map((todo, index) => (
            <ToDo key={todo.id} value={todo.id} deleteItem={this.deleteItem.bind(this)} {...todo} />


          ))}
            </table>
          </div>
        );
      }
    }

Isolated code in question:

    // this is the issue

    deleteItem(event) {

    const clickedId = event.target.value;
    //console.log(clickedId);
    const arrDes = [...this.state.list];
    const newList = this.state.list.filter((item) => {

    //console.log(item.id);
    return item.id !== clickedId;
    })
    this.setState({
      list: newList
    });
  }

2 Answers 2

1

You need to cast clickedId to a natural number to match the id of the list element:

const newList = this.state.list.filter(item => {
    return item.id !== +clickedId      
});

The + operator is one way to do that.

Sign up to request clarification or add additional context in comments.

2 Comments

This explains where I went wrong. How would have I found this on my own?
@K.Arthur I did console.log(this.state.list, clickedId) and noticed the Id mismatch. It was subtle for sure.
1

Your function can be simplified:

deleteItem(event) {

  // Grab the value from the clicked button by
  // using destructuring to pick out that property 
  const { value } = event.target;

  // return an array that doesn't include objects with ids
  // that match the value - coerced to a number from a string
  // so it matches the id type in your data
  const newList = this.state.list.filter(item => item.id !== Number(value));
  this.setState({ list: newList });
}

2 Comments

I am grateful for the explanation. It provides a lot of information that I much needed. Any links where I can learn more of this on my own? Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.