8. How To Use State In Your Component#

8.1. Store Questions And Answers In The State#

To manipulate the FAQ, we will move all the data to the state of the component. The state of the component is the local state of that specific component. When the state changes, the component re-renders itself. We can initialize the state in our functional component body using the useState hook.

 1import { useState } from "react";
 2import "./App.css";
 3import FaqItem from "./components/FaqItem";
 4
 5function App() {
 6  const [faqList, setFaqList] = useState([
 7    {
 8      question: "What does the Plone Foundation do?",
 9      answer: "The mission of the Plone Foundation is to protect and...",
10    },
11    {
12      question: "Why does Plone need a Foundation?",
13      answer: "Plone has reached critical mass, with enterprise...",
14    },
15  ]);
16
17  return (
18    <ul>
19      {faqList.map((item, index) => (
20        <FaqItem key={index} question={item.question} answer={item.answer} />
21      ))}
22    </ul>
23  );
24}
25
26export default App;
Differences
--- a/src/App.js
+++ b/src/App.js
@@ -1,30 +1,24 @@
+import { useState } from "react";
 import "./App.css";
 import FaqItem from "./components/FaqItem";

 function App() {
+  const [faqList, setFaqList] = useState([
+    {
+      question: "What does the Plone Foundation do?",
+      answer: "The mission of the Plone Foundation is to protect and...",
+    },
+    {
+      question: "Why does Plone need a Foundation?",
+      answer: "Plone has reached critical mass, with enterprise...",
+    },
+  ]);
+
   return (
     <ul>
-      <FaqItem
-        question="What does the Plone Foundation do?"
-        answer="
-          The mission of the Plone Foundation is to protect and promote Plone.
-          The Foundation provides marketing assistance, awareness, and
-          evangelism assistance to the Plone community. The Foundation also
-          assists with development funding and coordination of funding for
-          large feature implementations. In this way, our role is similar to
-          the role of the Apache Software Foundation and its relationship with
-          the Apache Project."
-      />
-      <FaqItem
-        question="Why does Plone need a Foundation?"
-        answer="
-          Plone has reached critical mass, with enterprise implementations and
-          worldwide usage. The Foundation is able to speak for Plone, and
-          provide strong and consistent advocacy for both the project and the
-          community. The Plone Foundation also helps ensure a level playing
-          field, to preserve what is good about Plone as new participants
-          arrive."
-      />
+      {faqList.map((item, index) => (
+        <FaqItem key={key} question={item.question} answer={item.answer}
+       />
+      ))}
     </ul>
   );
 }

8.2. Exercise#

To save space in the view, we want to show and hide the answer when you click on the question. Add a state variable to the FaqItem component, which keeps the state of the answer being shown or not, and adjust the render method to show or hide the answer.

Solution

components/FaqItem.jsx

 1import { useState } from "react";
 2import "./FaqItem.css";
 3import PropTypes from "prop-types";
 4
 5const FaqItem = (props) => {
 6  const [isAnswer, setAnswer] = useState(false);
 7  return (
 8    <li className="faq-item">
 9      <h2 className="question">{props.question}</h2>
10      {isAnswer && <p>{props.answer}</p>}
11    </li>
12  );
13};
14
15FaqItem.propTypes = {
16  question: PropTypes.string.isRequired,
17  answer: PropTypes.string.isRequired,
18};
19
20export default FaqItem;
--- a/src/components/FaqItem.jsx
+++ b/src/components/FaqItem.jsx
@@ -1,11 +1,13 @@
+import { useState } from "react";
 import "./FaqItem.css";
 import PropTypes from "prop-types";

 const FaqItem = (props) => {
+  const [isAnswer, setAnswer] = useState(false);
   return (
     <li className="faq-item">
       <h2 className="question">{props.question}</h2>
-      <p>{props.answer}</p>
+      {isAnswer && <p>{props.answer}</p>}
     </li>
   );
 };