본문 바로가기
개발/React

리액트 - FAQ 카테고리 만들기

by 피로물든딸기 2022. 3. 1.
반응형

리액트 전체 링크

 

아래의 카테고리대로 선택할 수 있게 되었으니,

const categories = [
  {
    name: "자주 묻는 질문",
    value: "all",
  },
  {
    name: "카테고리 1",
    value: "category1",
  },
  {
    name: "카테고리 2",
    value: "category2",
  },
  {
    name: "카테고리 3",
    value: "category3",
  },
];

 

FAQ 목록을 각 카테고리 별로 분류하도록 해보자.

const qnaList = [
  {
    category: "category1",
    question: "what is that ? 1",
    answer: "this is react. 1",
  },
  {
    category: "category2",
    question: "what is that ? 2",
    answer: "this is react. 2",
  },
  {
    category: "category3",
    question: "what is that ? 3",
    answer: "this is react. 3",
  },
  {
    category: "category1",
    question: "what is that ? 4",
    answer: "this is react. 4",
  },
  {
    category: "category2",
    question: "what is that ? 5",
    answer: "this is react. 5",
  },
  {
    category: "category3",
    question: "what is that ? 6",
    answer: "this is react. 6",
  },
];

 

실제로 보여주는 목록을 showList로 지정하여 qnaList로 초기화한다.

const [showList, setShowList] = useState(qnaList);

 

category가 변경될 때마다 showList를 filter를 이용하여 필터링하면 된다.

all인 경우는 모두 보여준다.

  useEffect(()=> {
    setShowList(
      qnaList.filter((item) => {
        if (category === "all") return true;
        if (category === item.category) return true;
        return false;
      })
    );
  }, [category]);

 

showList의 map을 이용하여 원하는 구성, css 등을 적용하여 보여주면 된다.

      <div className="fqa-parent">
        <div className="faq-list">
          {showList.map((item, index) => getQnACard(item, index))}     
        </div>
      </div>

 

여기에서는 아래와 같이 question과 answer를 구분하도록 하였다.

  const getQnACard = (item, index) => {
    return (
      <div className="faq-card" key={index}>
        <div
          className="faq-card-title"
          onClick={() => {
            let tempCard = cardOnOff;
            tempCard[index].show = !tempCard[index].show;
            setCardOnOff([...tempCard]);
          }}
        >
          <span className="question-mark">Q.</span>
          <span>{item.question}</span>
        </div>
        <div
          className={
            qnaList[index].show
              ? "faq-card-answer"
              : "faq-card-answer faq-card-none"
          }
        >
          <span className="answer-mark">A.</span>
          <span className="FAQ-card-answer">{item.answer}</span>
        </div>
      </div>
    );
  };

 

최종 코드는 아래와 같다.

import React, { useEffect, useState } from "react";
import CategoryFilter from "../components/CategoryFilter";

import "../css/FAQ.css";

const categories = [
  {
    name: "자주 묻는 질문",
    value: "all",
  },
  {
    name: "카테고리 1",
    value: "category1",
  },
  {
    name: "카테고리 2",
    value: "category2",
  },
  {
    name: "카테고리 3",
    value: "category3",
  },
];

const qnaList = [
  {
    category: "category1",
    question: "what is that ? 1",
    answer: "this is react. 1",
  },
  {
    category: "category2",
    question: "what is that ? 2",
    answer: "this is react. 2",
  },
  {
    category: "category3",
    question: "what is that ? 3",
    answer: "this is react. 3",
  },
  {
    category: "category1",
    question: "what is that ? 4",
    answer: "this is react. 4",
  },
  {
    category: "category2",
    question: "what is that ? 5",
    answer: "this is react. 5",
  },
  {
    category: "category3",
    question: "what is that ? 6",
    answer: "this is react. 6",
  },
];

const FAQ = () => {
  const [category, setCatecory] = useState("all");
  const [cardOnOff, setCardOnOff] = useState(qnaList);
  const [showList, setShowList] = useState(qnaList);

  const getQnACard = (item, index) => {
    return (
      <div className="faq-card" key={index}>
        <div
          className="faq-card-title"
          onClick={() => {
            let tempCard = cardOnOff;
            tempCard[index].show = !tempCard[index].show;
            setCardOnOff([...tempCard]);
          }}
        >
          <span className="question-mark">Q.</span>
          <span>{item.question}</span>
        </div>
        <div
          className={
            qnaList[index].show
              ? "faq-card-answer"
              : "faq-card-answer faq-card-none"
          }
        >
          <span className="answer-mark">A.</span>
          <span className="FAQ-card-answer">{item.answer}</span>
        </div>
      </div>
    );
  };

  useEffect(()=> {
    setShowList(
      qnaList.filter((item) => {
        if (category === "all") return true;
        if (category === item.category) return true;
        return false;
      })
    );
  }, [category]);

  return (
    <div>
      <div>faq</div>
      <CategoryFilter
        categories={categories}
        category={category}
        setCatecory={setCatecory}
      />
      <div className="fqa-parent">
        <div className="faq-list">
          {showList.map((item, index) => getQnACard(item, index))}     
        </div>
      </div>
    </div>
  );
};

export default FAQ;

 

.fqa-parent {
  display: flex;
  align-items: center;
  justify-content: center;
}

.faq-list {
  width: 80%;
}

.faq-card {
  display: flex;
  margin-top: 10px;
  width: 100%;
  padding-left: 1.25rem;
  padding-right: 1.25rem;
  border: 1px solid black;
  border-radius: 20px;
  flex-direction: column;
}

.faq-card-title {
  display: flex;
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
  align-items: center;
  cursor: pointer;
}

.faq-card-answer {
  position: relative;
  padding-top: 1rem;
  padding-bottom: 1.5rem;
  padding-right: 2rem;
  border: 0px solid rgba(225,228,230,.5);
  border-top-width: 1px;
}

.faq-card-none {
  display: none;
}

.question-mark {
  color: rgb(12, 77, 162);
  font-size: 20px;
  margin-right: 10px;
}

.answer-mark {
  color: skyblue;
  font-size: 20px;
  margin-right: 10px;
}
반응형

댓글