16. Use Lifecycle Methods

Lifecycle methods are methods which are called on specific external events. For example the componentDidMount method is called when the component gets added to the dom. We can use this method to do additional calls. For example in our case we want to fetch the initial data from the backend.

31componentDidMount() {
32  this.props.getFaqItems();
33}

The getFaqItems method is mapped using the connect call. The full Faq component will now look like this:

 1import React, { Component } from "react";
 2import { connect } from "react-redux";
 3import PropTypes from "prop-types";
 4
 5import FaqItem from "./FaqItem";
 6import { addFaqItem, getFaqItems } from "../actions";
 7
 8class Faq extends Component {
 9  static propTypes = {
10    faq: PropTypes.arrayOf(
11      PropTypes.shape({
12        question: PropTypes.string.isRequired,
13        answer: PropTypes.string.isRequired
14      })
15    ),
16    addFaqItem: PropTypes.func.isRequired,
17    getFaqItems: PropTypes.func.isRequired
18  };
19
20  constructor(props) {
21    super(props);
22    this.state = {
23      question: "",
24      answer: ""
25    };
26  }
27
28  componentDidMount() {
29    this.props.getFaqItems();
30  }
31
32  onChangeQuestion = (event) => {
33    this.setState({
34      question: event.target.value
35    });
36  }
37
38  onChangeAnswer = (event) => {
39    this.setState({
40      answer: event.target.value
41    });
42  }
43
44  onSubmit = (event) => {
45    this.props.addFaqItem(this.state.question, this.state.answer);
46    this.setState({
47      question: "",
48      answer: ""
49    });
50    event.preventDefault();
51  }
52
53  render() {
54    return (
55      <div>
56        <ul>
57          {this.props.faq.map((item, index) => (
58            <FaqItem
59              question={item.question}
60              answer={item.answer}
61              index={index}
62            />
63          ))}
64        </ul>
65        <form onSubmit={this.onSubmit}>
66          <label>
67            Question:
68            <input
69              name="question"
70              type="text"
71              value={this.state.question}
72              onChange={this.onChangeQuestion}
73            />
74          </label>
75          <label>
76            Answer:
77            <textarea
78              name="answer"
79              value={this.state.answer}
80              onChange={this.onChangeAnswer}
81            />
82          </label>
83          <input type="submit" value="Add" />
84        </form>
85      </div>
86    );
87  }
88}
89
90export default connect(
91  (state, props) => ({
92    faq: state.faq
93  }),
94  { addFaqItem, getFaqItems }
95)(Faq);

Differences

--- a/src/components/Faq.jsx
+++ b/src/components/Faq.jsx
@@ -3,7 +3,7 @@ import { connect } from "react-redux";
import PropTypes from "prop-types";

import FaqItem from "./FaqItem";
-import { addFaqItem } from "../actions";
+import { addFaqItem, getFaqItems } from "../actions";

class Faq extends Component {
  static propTypes = {
@@ -13,7 +13,8 @@ class Faq extends Component {
        answer: PropTypes.string.isRequired
      })
    ),
-    addFaqItem: PropTypes.func.isRequired
+    addFaqItem: PropTypes.func.isRequired,
+    getFaqItems: PropTypes.func.isRequired
  };

  constructor(props) {
@@ -27,6 +28,10 @@ class Faq extends Component {
    };
  }

+  componentDidMount() {
+    this.props.getFaqItems();
+  }
+
  onChangeQuestion = (event) => {
    this.setState({
      question: event.target.value
@@ -89,5 +94,5 @@ export default connect(
  (state, props) => ({
    faq: state.faq
  }),
-  { addFaqItem }
+  { addFaqItem, getFaqItems }
)(Faq);