Web/Frontend

[MBTI 테스트 사이트 만들기 #3] 테스트 질문지 만들기

AllTheTech 2023. 9. 21. 18:46

이전 글 보러 가기 👉 [MBTI 테스트 사이트 만들기 #2] 이메일 보내기 버튼 만들기

[MBTI 테스트 사이트 만들기 #3] 테스트 질문지 만들기

각 테스트를 보여줄 메인 화면을 완성했다.

이제 심리 테스트를 하나 만들어보자. 각 테스트에 관한 정보는 datas 배열에 담고 있다. 내가 만들고 있는 고양이 성격 테스트는 질문 12가지와 결과 12가지로 구성하려고 한다.

테스트 정보가 담긴 datas 배열

import catBTI_banner from "../assets/img/catBTI/catBTI_banner.png";
import catBTI_full from "../assets/img/catBTI/catBTI_full.png";

export const datas = [
  //catBTI - 고양이 성격 테스트
  {
    info: {
      mainTitle: "고양이 성격 테스트",
      subTitle: "주인님 행동을 통해 성격을 알아보자!",
      mainUrl: "catBTI",
      scoreType: "typeMBTI",
      mainImage: catBTI_banner,
      fullImage: catBTI_full,
      resultImage: "../../assets/img/catBTI/catBTI_result.jpg",
    },
    questions: [
      {
        questionText:
          "방에 손님이 찾아왔을 때 고양이의 행동은?",
        answers: [
          {
            type: "E",
            content: "호기심 발동! 주변을 어슬렁거린다",
          },
          {
            type: "I",
            content: "경계모드! 책상밑이나 구석으로 숨어버린다",
          },
        ],
      },
      
      ...
      
    ],
    results: [
      {
        type: "ISTJ",
        result: `고양이계의 흥선대원군`,
        content: '경계심이 많지만, 내 가족에겐 충성심 강한 고양이예요. ...'
      },
      
      ...
      
     ]
  },
];
  • info: 테스트의 제목, 부제목, 썸네일, 메인이미지 등 테스트에 필요한 정보 데이터
    • mainUrl: 테스트 url 
    • scoreType: 테스트의 유형(점수기준인지, mbti Type기준인지 등)
    • mainImage: 테스트 썸네일(메인 페이지에서 보여줄 이미지)
    • fullImage: 테스트 상세 페이지(테스트 시작 화면에서 보여줄 이미지)
  • questions: 테스트 질문, 답변(타입)
  • results: 테스트 대답에 따른 결과 데이터

메인 페이지에서의 datas

만들어진 datas 배열 데이터를 받아서 메인 페이지의 테스트 카드를 만들었다.

//Main > Content.js

import React, { useContext } from "react";
import { Link } from "react-router-dom";
import { datas } from "../../data/data"; //테스트 정보가 담긴 데이터

...

function Content() {
...

  return (
    <div>
 	...
      {/* 각 테스트 카드 */}
      <div>
        {datas.map((item, idx) => {
          return (
            <Link
              style={styles.testWrap}
              to={item.info.mainUrl}
              key={item.info.mainUrl}
            >
              <img
                style={styles.testImg}
                loading="lazy"
                src={item.info.mainImage}
                alt={item.info.mainUrl}
                width={"100%"}
              />
              <div style={styles.titleWrap}>
                <h2 style={styles.mainTitle}>👉{item.info.mainTitle}👈</h2>
                <h3 style={styles.subTitle}>{item.info.subTitle}</h3>
              </div>
            </Link>
          );
        })}
      </div>
    </div>
  );
}

const styles = {
  bannerImage: {
    display: "block",
    margin: "0 auto",
    maxWidth: "100%",
    height: "auto",
  },
  testWrap: {
    margin: "30px auto 30px auto",
    display: "flex",
    justifyContent: "center",
    alignItems: "center",
    flexDirection: "column",
    overflow: "hidden",
    textDecoration: "none",
  },
  testImg: {},
  titleWrap: {
    textAlign: "center",
    width: "100%",
  },
  mainTitle: { margin: "10px auto", fontSize: "1.5em", fontWeight: "bold" },
  subTitle: { margin: "10px auto" },
};

export default Content;
  • map 함수를 사용하여 datas 배열의 각 항목을 순회하고, 각 항목에 대한 정보를 사용하여 테스트 카드 컴포넌트를 생성하고 렌더링 함
  • 각 테스트 카드 컴포넌트는 Link 컴포넌트로 래핑되어, 해당 테스트 카드를 클릭했을 때 특정 URL로 이동할 수 있도록 함

테스트 동적 라우트 생성

//App.js

import React, { useEffect, useState } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";

import Main from "./components/pages/Main";
import { datas } from "./data/data";
import Quiz from "./components/pages/Quiz";

function App() {
  const [testUrl, setTestUrl] = useState([]);

  useEffect(() => {
    datas.map((item, idx) => {
      setTestUrl([...testUrl, `/${item.info.mainUrl}`]);
    });
  }, []);

  return (
    <div className="App">
      <BrowserRouter>
   		...
        <Routes>
          {/* Main */}
          <Route path="/" element={<Main />} />
          
          {/* 테스트 상세 페이지 */}
          {testUrl.map((item) => (
            <Route
              path={item}
              element={<Quiz test={item} />}
              key={item}
              exact
            />
          ))}
          
        </Routes>
      	...
      </BrowserRouter>
    </div>
  );
}

export default App;
  • testUrl 배열에 있는 각 테스트 페이지의 URL 경로를 기반으로 동적으로 경로와 컴포넌트를 설정하여, 사용자가 해당 URL로 이동하면 해당 테스트의 정보를 가진 Quiz 컴포넌트가 렌더링되도록 함

테스트 상세 화면

반응형