lil.dev
Published on

๐ŸŽ‰ ์ปฌ๋Ÿฌ๋ฆฌ์ŠคํŠธ ํ”„๋กœ์ ํŠธ #14 ๋ฌด์ž‘์œ„ ๋žœ๋ค ๋ฒ„ํŠผ ๋งŒ๋“ค๊ธฐ

๊ธ€์“ด์ด

    ๐Ÿ“Œ ๋ชฉ์ฐจ

    Welcome

    โœจ ์ปฌ๋Ÿฌ๋ฆฌ์ŠคํŠธ ์‚ฌ์ดํŠธ(์•„์ง ์—†์Œ

    ๐Ÿ’๐Ÿป

    1. ๋ฌธ์ œ๋ฅผ ๋ฌด์ž‘์œ„๋กœ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋žœ๋ค ๋ฒ„ํŠผ ๋งŒ๋“ค๊ธฐ 1-1. qList.json์— index ๋‹ฌ๊ธฐ 1-2. ์ฃผ์†Œ์˜ path variable(params)์— ๋”ฐ๋ผ์„œ ํŽ˜์ด์ง€ ๋ Œ๋”๋ง 1-3. ๋žœ๋ค ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๋ฌด์ž‘์œ„ id๋กœ ์ด๋™

    1-1. qList.json์— index ๋‹ฌ๊ธฐ

    ์˜ค๋Š˜์€ ๋žœ๋ค ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ
    ๋ฌด์ž‘์œ„๋กœ ๋‹ค์–‘ํ•œ ๋ฌธ์ œ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋„๋ก
    ๋ฒ„ํŠผ์„ ๋งŒ๋“ค๊ณ  ๋ผ์šฐํŒ…์„ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

    ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ ๋งˆ๋‹ค ๋‹ค๋ฅธ ๋ฌธ์ œ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ด์•ผํ•˜๋ฏ€๋กœ
    ์ฃผ์†Œ๋ฅผ ์ด๋™ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋‹จ ๋ฌธ์ œ๋งˆ๋‹ค id๋ฒˆํ˜ธ๋ฅผ ๋ถ™์—ฌ์ค๋‹ˆ๋‹ค.

    json์— id ๋‹ฌ๊ธฐ

    const qlist = {
      quiz: [
        // ...
      ],
    }
    
    // quiz์˜ ๋‚ด์šฉ์€?
    qlist.quiz
    //(26)ย [{โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}]
    
    // quiz์˜ ์ฒซ ๋ฒˆ์งธ ๊ฐ’์€?
    qlist.quiz[0]
    // {class: '2022๋…„๋„ 2ํšŒ์ฐจ ๊ธฐ์ถœ', type: '1', quizContent: '๋”ฐ๋œปํ•˜๊ณ  ํ’์š”๋กœ์šด ์ด๋ฏธ์ง€์™€ ์ฐจ๊ฐ‘๊ณ  ์“ธ์“ธํ•œ ์ด๋ฏธ์ง€ ๋‘๊ฐ€์ง€๋ฅผ ์—ฐ์ถœํ•ด ๋ณด์„ธ์š”.', condition: '(3์ƒ‰์ƒ ์ด์ƒ 10์นธ ์ด์ƒ)'}
    
    // ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌ
    qlist.quiz.map((q) => ({ ...q }))
    //(26)ย [{โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}, {โ€ฆ}]
    
    // ๋ณต์‚ฌํ•œ ๊ฐ’์— index๋ฅผ id๋กœ ์ถ”๊ฐ€
    qlist.quiz.map((q, index) => ({ ...q, id: index + 1 }))
    // {
    //   class: "2022๋…„๋„ 2ํšŒ์ฐจ ๊ธฐ์ถœ"
    //   condition: "(3์ƒ‰์ƒ ์ด์ƒ 10์นธ ์ด์ƒ)"
    //   id: 1
    //   quizContent: "๋”ฐ๋œปํ•˜๊ณ  ํ’์š”๋กœ์šด ์ด๋ฏธ์ง€์™€ ์ฐจ๊ฐ‘๊ณ  ์“ธ์“ธํ•œ ์ด๋ฏธ์ง€ ๋‘๊ฐ€์ง€๋ฅผ ์—ฐ์ถœํ•ด ๋ณด์„ธ์š”."
    //   type: "1"
    // }
    
    // id๊ฐ€ ์ถ”๊ฐ€๋œ quiz๋ฅผ JSON ๋ฌธ์ž์—ด๋กœ ์ง๋ ฌํ™”
    JSON.stringify(qlist.quiz.map((q, index) => ({ ...q, id: index + 1 })))
    

    1-2. ์ฃผ์†Œ์˜ path variable(params)์— ๋”ฐ๋ผ์„œ ํŽ˜์ด์ง€ ๋ Œ๋”๋ง

    index.tsx์—์„œ params๋ฅผ ์ด์šฉํ•ด id๋กœ ๋ผ์šฐํŒ…ํ•˜๋„๋ก ํ•ด์ฃผ์—ˆ๋‹ค.

    //use params ๋ฌธ์„œ ๋ณด๊ธฐ (react router dom๋ฌธ์„œ์—์„œ)

    //index.tsx
    ;<Route path="/quiz/:quizId" element={<TestForm />} />
    {
      /* /problem/:problemId */
    }
    {
      /* /problem/1 */
    }
    {
      /* /problem/2 */
    }
    

    ๊ทธ๋‹ค์Œ Testform.tsx์—์„œ ๋ฌธ์ œ๋ณ„ id๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ๋‹ค.

    //Testform.tsx
    
    const params = useParams() // url์— ์žˆ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ(path variable, dynamic routes)๋ฅผ ๊ฐ€์ ธ์˜ด!
    // ?? ๋„ ๋ณ‘ํ•ฉ ์—ฐ์‚ฐ์ž. ์™ผ์ชฝ์ด null์ด๋‚˜ undefined๋ฉด ์˜ค๋ฅธ์ชฝ์˜ ๊ฐ’์„ fallback์œผ๋กœ ์จ๋ผ
    const quizId = parseInt((params['quizId'] as string | undefined) ?? '1') // ex 1
    const quiz = QuizList.quiz[quizId - 1] // index๋Š” 0๋ถ€ํ„ฐ ์…ˆ์œผ๋กœ...
    

    1-3. ๋žœ๋ค ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๋ฌด์ž‘์œ„ id๋กœ ์ด๋™

    ๋‹ค์Œ์œผ๋กœ ๋ฌด์ž‘์œ„๋กœ ์ˆซ์ž๋ฅผ ๋„ฃ์–ด ๋ฌธ์ œ ์ˆ˜ ์•ˆ์—์„œ ๋žœ๋ค์œผ๋กœ ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋Š” link๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์—ˆ๋‹ค.

    <Link to={`/quiz/${Math.min(Math.floor(Math.random() * 26 + 1), 26)}`}>๋ฌด์ž‘์œ„ ๋ฌธ์ œ ๋ณด๊ธฐ</Link>
    

    ์œ„์˜ ์‹์€ ์•„๋ž˜์™€ ๊ฐ™์€ ์ˆœ์„œ๋กœ ๋งŒ๋“ค์–ด์กŒ๋‹ค.

    // 0๋ถ€ํ„ฐ 1์‚ฌ์ด์˜ ๊ฐ’
    Math.random()
    
    // 0๋ถ€ํ„ฐ 26์‚ฌ์ด์˜ ๊ฐ’
    Math.random() * 26
    
    // 1๋ถ€ํ„ฐ 27 ์‚ฌ์ด์˜ ๊ฐ’ (์†Œ์ˆ˜ ํฌํ•จ)
    Math.random() * 26 + 1
    
    // 1๋ถ€ํ„ฐ 27์‚ฌ์ด์˜ ์ •์ˆ˜ (27์ด ๋‚˜์˜ฌ ๊ฐ€๋Šฅ์„ฑ์ด ๋งค์šฐ๋งค์šฐ ์ ์Œ)
    Math.floor(Math.random() * 26 + 1)
    
    // 1๋ถ€ํ„ฐ 26์‚ฌ์ด์˜ ๊ฐ’
    Math.min(Math.floor(Math.random() * 26 + 1), 26)
    

    ๊ทธ ๋‹ค์Œ ํ•ด๋‹น ๋ฌธ์ œ์— ๋งž๋Š” ๋‚ด์šฉ๊ณผ ์กฐ๊ฑด์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๊ฒŒ ๋ฆฌํ„ด ๊ฐ’์„ ์กฐ์ •ํ–ˆ๋‹ค.

    <div className="quiz-paragraph">
      <a className="category" href="">
        {quiz.class}
      </a>
      <h1 className="text-2xl mb-2">Q. {quiz.quizContent}</h1>
      <h2 id="condition" className="text-lg">
        {quiz.condition}
      </h2>
    </div>