How to link an id from an object in an array to a button onClick?

Viewed 513

I am trying to learn React with Firebase and I am doing this project where I have a To-do-list. Now I have added delete buttons to each to-do-object in order to delete that specific to-do-object in the list. The problem is that I don't know how to link the specific object Id that I want to delete to the button.

This is the part of the code I am talking about. The deleteTodo component receives an array of to do-objects. I now want to create a delete button that sends the specific id of the object to the deleteTodo-function in order to handle that in my Firestore.

import React, { Component } from "react";
import { connect } from "react-redux";
import { deleteTodo } from "../../store/actions/todoActions";

class DeleteTodo extends Component {
  onClick = id => {
    console.log("ID: ", id);
// this.props.deleteTodo(id[0]); -- This deletes the first object of the list. But I want the object linked to the delete button to be removed.
  };

  render() {
    return (
      <div>
        <button onClick={() => this.onClick(this.props.todos)} style={btnStyle}> // How do I send in the object Id of the object that I want to delete here?
          x
        </button>
      </div>
    );
  }
}

const btnStyle = {
//...code...
};

const mapStateToProps = state => {
  return {
    todos: state.firestore.ordered.todos || state.todo.todos

  };
};

const mapDispatchToProps = dispatch => {
  // console.log("2: inside mapDispatchToProps - dispatch ", dispatch);
  return {
    deleteTodo: todo => dispatch(deleteTodo(todo))
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(DeleteTodo);

console.log("ID: ", id);

ID:  
(5) [{…}, {…}, {…}, {…}, {…}]
0: {id: "12uKF2ILtP063NQiMEwH", completed: false, title: "2"}
1: {id: "6dxSrbk19KccS9qsYt46", completed: false, title: "4"}
2: {id: "Fcs5yJZYD2JZkWURKtPq", completed: false, title: "1"}
3: {id: "ZfxpFsLdWORDLqMCxV3R", completed: false, title: "3"}
4: {id: "foHKMdmzpVXAOHmpqabi", completed: false, title: "5"}
length: 5
__proto__: Array(0)

PS. Also not very happy about the order of the objects in the list. I kinda want them to be in the order I added them (1,2,..,5) but that is not the main issue here.

1 Answers

You can use an arrow function to pass the ID of the item to the onClick handler. So for example (just the render method):

render() {
 const todos = this.props.todos.slice();
 todos.sort((a, b) => a.title.localeCompare(b.title)); // Sort the TODOs by title
 return <div>
   <ul>
   {todos.map(item => <li>
        <span>{item.title}</span>
        <button onClick={() => this.onClick(item.id)} style={btnStyle}>
          x
        </button>
    </li>)}
   </ul>
 </div>;
}

This will render the items in an unordered list (item title), each with a delete button. On clicking on the button, the id of the corresponding item will be passed to the onClick handler.

UPD: Added slice to create a shallow copy of the todos array from props.

Related