📓 4.2.3.6 Deleting a Ticket
In the last lesson, we added the ability for a user to see an individual ticket's detail page. We had to alter or create four different components in order to add this relatively small piece of functionality.
However, some good news. Adding delete functionality to our application is going to be much easier. This is because we planned out our application carefully. We will only need to alter two components — TicketControl (which holds our shared state) and TicketDetail (where the delete button will live).
If we'd chosen to place TicketDetail below Ticket in the component tree, we'd have a prop-drilling nightmare. Our function for deleting tickets would affect four different components because we'd need to pass it as a prop through TicketList, Ticket and TicketDetail.
Here are the steps we will need to take to add delete functionality to our Help Queue:
- Write a
handleDeletingTicketfunction inTicketControl. This function will update the state of themainTicketList. - Pass this function down as a prop to
TicketDetail. We will call this proponClickingDelete. - Add a button to
TicketDetailwith anonClickevent handler that will triggeronClickingDelete. - As always, we will need to add a PropType for
onClickingDelete.
handleDeletingTicket Function
We will start by adding a function to our TicketControl component that will delete a ticket from the mainTicketList based on its ID. Once again, we can write this function in isolation without worrying about how it will interact with other components yet.
const handleDeletingTicket = (id) => {
const newMainTicketList = mainTicketList.filter(ticket => ticket.id !== id);
setMainTicketList(newMainTicketList);
setSelectedTicket(null);
}
handleDeletingTicket will take an id as a parameter.
We will use the filter() method again. This time, though, we want the newMainTicketList to filter everything that doesn't have the ticket ID that will be passed into the function. In other words, we are filtering out the ticket that has the specified ID because we want it to be deleted from the list.
Next, we call setMainTicketList to update the state of mainTicketList to our filtered newMainTicketList.
Finally, we also need to set selectedTicket back to null. That way, once a ticket is closed, TicketControl will ensure that the TicketList component is showing.
Passing handleDeletingTicket as Prop to TicketDetail
Next, we need to pass our handleDeletingTicket function as a prop to TicketDetail. This just involves a small change in our conditional rendering:
if (selectedTicket != null) {
currentlyVisibleState =
<TicketDetail
ticket={selectedTicket}
onClickingDelete={handleDeletingTicket} />
buttonText = "Return to Ticket List";
}
Adding a Delete Button and PropType to TicketDetail
We just need to make a few small changes to our TicketDetail component:
import React from "react";
import PropTypes from "prop-types";
function TicketDetail(props){
const { ticket, onClickingDelete } = props;
return (
<React.Fragment>
<h1>Ticket Detail</h1>
<h3>{ticket.location} - {ticket.names}</h3>
<p><em>{ticket.issue}</em></p>
<button onClick={() => onClickingDelete(ticket.id)}>Close Ticket</button>
<hr/>
</React.Fragment>
);
}
TicketDetail.propTypes = {
ticket: PropTypes.object,
onClickingDelete: PropTypes.func
};
export default TicketDetail;
First, we add a button with an onClick handler. When the button is clicked, onClickingDelete(ticket.id) will be executed. Once again, we need to use () => in our JSX curly braces because our function has parens with an argument. Also note that we're destructuring props to create an onClickingDelete variable, just like we did for ticket.
Finally, we need to add a PropType for onClickingDelete.
And that's it! We didn't have to add too much code, in large part because we didn't do any prop-drilling.