9. Use Callbacks To Delete An Item

9.1. Add Delete Button

To be able to manage our FAQ entries we start by adding a delete button to remove an item from the list. Add the delete button to the FaqItem view in the FaqItem.jsx file and create an empty onDelete handler which is called when the button is pressed.

Solution

 1import React, { Component } from "react";
 2import PropTypes from "prop-types";
 3import "./FaqItem.css";
 4
 5class FaqItem extends Component {
 6  static propTypes = {
 7    question: PropTypes.string.isRequired,
 8    answer: PropTypes.string.isRequired
 9  };
10
11  constructor(props) {
12    super(props);
13    this.state = {
14      show: false
15    };
16  }
17
18  toggle = () => {
19    this.setState({
20      show: !this.state.show
21    });
22  }
23
24  onDelete = () => {}
25
26  render() {
27    return (
28      <li className="faq-item">
29        <h2 onClick={this.toggle} className="question">
30          {this.props.question}
31        </h2>
32        {this.state.show && <p>{this.props.answer}</p>}
33        <button onClick={this.onDelete}>Delete</button>
34      </li>
35    );
36  }
37}
38
39export default FaqItem;
--- a/src/components/FaqItem.jsx
+++ b/src/components/FaqItem.jsx
@@ -11,6 +11,7 @@ class FaqItem extends Component {
  constructor(props) {
    super(props);
    this.state = {
      show: false
    };
@@ -22,6 +23,8 @@ class FaqItem extends Component {
    });
  }

+  onDelete = () => {}
+
  render() {
    return (
      <li className="faq-item">
@@ -29,6 +32,7 @@ class FaqItem extends Component {
          {this.props.question}
        </h2>
        {this.state.show && <p>{this.props.answer}</p>}
+        <button onClick={this.onDelete}>Delete</button>
      </li>
    );
  }

9.2. Write The onDelete Handler

Now that we have our dummy handler ready we need to add functionality to the handler. Since the list of FAQ items is managed by our App component we can not directly remove the item. Rewrite the FaqItem component so that a unique identifier of the FAQ item and a callback to remove the FAQ item can be passed to this component. Also complete the onDelete handler so it will call the callback with the correct identifier.

Solution

 1import React, { Component } from "react";
 2import PropTypes from "prop-types";
 3import "./FaqItem.css";
 4
 5class FaqItem extends Component {
 6  static propTypes = {
 7    question: PropTypes.string.isRequired,
 8    answer: PropTypes.string.isRequired,
 9    index: PropTypes.number.isRequired,
10    onDelete: PropTypes.func.isRequired
11  };
12
13  constructor(props) {
14    super(props);
15    this.state = {
16      show: false
17    };
18  }
19
20  toggle = () => {
21    this.setState({
22      show: !this.state.show
23    });
24  }
25
26  onDelete = () => {
27    this.props.onDelete(this.props.index);
28  }
29
30  render() {
31    return (
32      <li className="faq-item">
33        <h2 onClick={this.toggle} className="question">
34          {this.props.question}
35        </h2>
36        {this.state.show && <p>{this.props.answer}</p>}
37        <button onClick={this.onDelete}>Delete</button>
38      </li>
39    );
40  }
41}
42
43export default FaqItem;
--- a/src/components/FaqItem.jsx
+++ b/src/components/FaqItem.jsx
@@ -5,7 +5,9 @@ import "./FaqItem.css";
class FaqItem extends Component {
  static propTypes = {
    question: PropTypes.string.isRequired,
-    answer: PropTypes.string.isRequired
+    answer: PropTypes.string.isRequired,
+    index: PropTypes.number.isRequired,
+    onDelete: PropTypes.func.isRequired
  };

  constructor(props) {
@@ -23,7 +25,9 @@ class FaqItem extends Component {
    });
  }

-  onDelete = () => {}
+  onDelete = () =>  {
+    this.props.onDelete(this.props.index);
+  }

  render() {
    return (

9.3. Write A Dummy Delete Handler

Now we’re ready to change the App component to add a dummy onDelete handler. Add the onDelete handler to the App component which logs the index of the FAQ item to the console. Make sure to pass the index and the callback to the FaqItem component to wire everything together:

Solution

 1import React, { Component } from "react";
 2import FaqItem from "./components/FaqItem";
 3import "./App.css";
 4
 5class App extends Component {
 6  constructor(props) {
 7    super(props);
 8    this.state = {
 9      faq: [
10        {
11          question: "What does the Plone Foundation do?",
12          answer:
13            "The mission of the Plone Foundation is to protect and..."
14        },
15        {
16          question: "Why does Plone need a Foundation?",
17          answer:
18            "Plone has reached critical mass, with enterprise..."
19        }
20      ]
21    };
22  }
23
24  onDelete = (index) => {
25    console.log(index);
26  }
27
28  render() {
29    return (
30      <ul>
31        {this.state.faq.map((item, index) => (
32          <FaqItem
33            question={item.question}
34            answer={item.answer}
35            index={index}
36            onDelete={this.onDelete}
37          />
38        ))}
39      </ul>
40    );
41  }
42}
43
44export default App;
--- a/src/App.js
+++ b/src/App.js
@@ -5,6 +5,7 @@ import "./App.css";
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      faq: [
        {
@@ -19,11 +20,20 @@ class App extends Component {
    };
  }

+  onDelete = (index) => {
+    console.log(index);
+  }
+
  render() {
    return (
      <ul>
-        {this.state.faq.map(item => (
-          <FaqItem question={item.question} answer={item.answer} />
+        {this.state.faq.map((item, index) => (
+          <FaqItem
+            question={item.question}
+            answer={item.answer}
+            index={index}
+            onDelete={this.onDelete}
+          />
        ))}
      </ul>
    );

9.4. Delete The FAQ Item From The List

The last step is to remove the item from the list. Write the onDelete handler which removes the item from the list and creates the new state.

Solution

23onDelete = (index) => {
24  let faq = this.state.faq;
25  faq.splice(index, 1);
26  this.setState({
27    faq
28  });
29}
--- a/src/App.js
+++ b/src/App.js
@@ -21,7 +21,11 @@ class App extends Component {
  }

  onDelete = (index) => {
-    console.log(index);
+    let faq = this.state.faq;
+    faq.splice(index, 1);
+    this.setState({
+      faq
+    });
  }

  render() {