๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป ํ”„๋กœ์ ํŠธ/๐Ÿ€ํ–‰์šด์˜ ๋กœ๋˜ ๋งˆ๋ฒ•์ง„๐Ÿ›ธ

[React, Next.js] ๋กœ๋˜ ๋งˆ๋ฒ•์ง„ ์‚ฌ์ดํŠธ ๋งŒ๋“ค๊ธฐ (2) - ํ”„๋ก ํŠธ ๋ชฉ์—…์„ ์œ„ํ•ด MSW ์„ค์น˜ํ•˜๊ณ  ๊ด€๋ จ ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ!

by hyeong._.ing 2026. 4. 30.

 

 

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋ฉด์„œ
๊ผญ ํ•ด๋ณด๊ณ  ์‹ถ์—ˆ๋˜ ๊ฒƒ ์ค‘ ํ•˜๋‚˜๋Š” ๋ชฉ์—…์ด์—ˆ๋‹ค.
๊ณผ์—ฐ ๋ชฉ์—…์ด ๋ฌด์—‡์ด๋ฉฐ,
React๋Š” ์–ด๋–ค์‹์œผ๋กœ ๋ชฉ์—…์„ ํ• ๊นŒ?

 

 

 

 

 

https://lotto-magic-frontend.vercel.app/

 

๋กœ๋˜ ๋ฒˆํ˜ธ ์ƒ์„ฑ ๋งˆ๋ฒ•์ง„

ํ–‰์šด ์š”์†Œ 3๊ฐœ๋ฅผ ์„ ํƒํ•˜๋ฉด ์˜ค๋Š˜์˜ ๋กœ๋˜ ๋ฒˆํ˜ธ์™€ ํ–‰์šด ์ ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์‚ฌ์ดํŠธ์ž…๋‹ˆ๋‹ค.

lotto-magic-frontend.vercel.app

 

 

 

 

 

 

1. ํ™˜๊ฒฝ๊ตฌ์„ฑ

  • React
  • Next.js
  • WebStorm
  • TypeScript

 

 


 

 

 

 

2. ๋ชฉ์—…(Mocking)

  • ๊ฐœ๋ฐœ์—์„œ์˜ ๋ชฉ์—…์€ ์‹ค์ œ ์ œํ’ˆ์ด๋‚˜ API๊ฐ€ ์•„์ง ์ค€๋น„๋˜์ง€ ์•Š์•˜์„ ๋•Œ, ๊ทธ ์—ญํ• ์„ ๋Œ€์‹ ํ•  ๊ฐ€์งœ ๋ฐ์ดํ„ฐ๋‚˜ ํ™˜๊ฒฝ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.
  • ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ ์‹œ ๋ฐฑ์—”๋“œ API ์„œ๋ฒ„๊ฐ€ ์™„์„ฑ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ , ๋ฏธ๋ฆฌ ์ •์˜๋œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ด์šฉํ•ด UI์™€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.
  • ๋‹ค์–‘ํ•œ ์ƒํ™ฉ ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค. ์„œ๋ฒ„ ์—๋Ÿฌ ๋“ฑ ์‹ค์ œ ์„œ๋ฒ„์—์„œ ์žฌํ˜„ํ•˜๊ธฐ ๋ฒˆ๊ฑฐ๋กœ์šด ์ƒํ™ฉ์„ ์‰ฝ๊ฒŒ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์™ธ๋ถ€ API ์ƒํƒœ์™€ ์ƒ๊ด€์—†์ด ํ”„๋ก ํŠธ์—”๋“œ ๋กœ์ง์˜ ์ •ํ™•์„ฑ๋งŒ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ๋…๋ฆฝ์ ์ธ ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

 

 


 

 

 

 

3. MSW(Mock Service Worker)

  • MSW๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ Service Worker API๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋„คํŠธ์›Œํฌ ์ˆ˜์ค€์—์„œ API ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„๊ณ , ๊ฐ€์งœ ์‘๋‹ต์„ ๋ณด๋‚ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.
  • ์‹ค์ œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์ด ๋‚˜๊ฐ€๋Š” ๊ฒฝ๋กœ๋ฅผ ์ค‘๊ฐ„์—์„œ ๊ฐ€๋กœ์ฑ„๊ธฐ ๋•Œ๋ฌธ์— ํ›จ์”ฌ ํ˜„์‹ค๊ฐ ์žˆ๋Š” ๋ชจํ‚น์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ํฌ๋กฌ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ Network ํƒญ์—์„œ ์š”์ฒญ์ด ์‹ค์ œ๋กœ ๋‚˜๊ฐ€๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๊ธฐ๋ก์ด ๋‚จ๋Š”๋‹ค. ๋””๋ฒ„๊น… ์‹œ ๋งค์šฐ ํฐ ์žฅ์ ์ด ๋œ๋‹ค.
  • MSW์˜ ๋™์ž‘ ๊ณผ์ •
    a) ์š”์ฒญ๋ฐœ์ƒ : ๋ฆฌ์•กํŠธ ์•ฑ์—์„œ fetch๋‚˜ axios๋ฅผ ํ†ตํ•ด API ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค.
    b) ์ธํ„ฐ์…‰ํŠธ : ๋ธŒ๋ผ์šฐ์ €์— ๋“ฑ๋ก๋œ Service Worker๊ฐ€ ์ด ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑˆ๋‹ค.
    c) ํ•ธ๋“ค๋Ÿฌํ™•์ธ : MSW์— ๋ฏธ๋ฆฌ ์ •์˜ํ•ด๋‘” ํ•ธ๋“ค๋Ÿฌ ์ค‘์— ํ•ด๋‹น ์š”์ฒญ ์ฃผ์†Œ์™€ ์ผ์น˜ํ•˜๋Š” ๊ฒƒ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
    d) ์‘๋‹ต๋ณ€ํ™˜ : ์ผ์น˜ํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ฐ€์งœ ์‘๋‹ต(JSON)์„ ๋ธŒ๋ผ์šฐ์ €์— ์ „๋‹ฌํ•œ๋‹ค. ๋งŒ์•ฝ ์—†๋‹ค๋ฉด ์‹ค์ œ ๋„คํŠธ์›Œํฌ๋กœ ์š”์ฒญ์„ ํ†ต๊ณผ์‹œํ‚จ๋‹ค.

 

 


 

 

 

4. MSW 

  • ์„ค์น˜ํ•˜๊ธฐ
    ํ”„๋กœ์ ํŠธ ๋‚ด์— ์žˆ๋Š” ํ„ฐ๋ฏธ๋„์— ๋“ค์–ด๊ฐ€์„œ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ ์–ด ์„ค์น˜ํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ --save-dev๋Š” ๊ฐœ๋ฐœ๊ณผ ํ…Œ์ŠคํŠธ ์‹œ์—๋งŒ ํ•„์š”ํ•œ ๋„๊ตฌ๋กœ ์šฉ๋„๋ฅผ ์ ์€ ๊ฒƒ์ด๊ธฐ์— ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์—์„œ๋Š” ์ œ์™ธ๋œ๋‹ค.
npm install msw --save-dev

 

 

 

  • ๋ธŒ๋ผ์šฐ์ €์— ์„œ๋น„์Šค ์›Œ์ปค ๋“ฑ๋กํ•˜๊ธฐ
    ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฐ–์œผ๋กœ ๋‚ด๋ณด๋‚ด๋Š” ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑŒ ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ์–ป๊ธฐ ์œ„ํ•ด ์„œ๋น„์Šค ์›Œ์ปค๋ฅผ ๋“ฑ๋กํ•œ๋‹ค. ์ด๋•Œ ๋“ฑ๋ก์„ ์™„๋ฃŒํ•˜๋ฉด public ๋””๋ ‰ํ† ๋ฆฌ์— MockServiceWorker๋ผ๋Š” ํŒŒ์ผ์ด ์ƒ๊ธด๋‹ค.
npx msw init public --save

์จ”์ž”~!

 

 

 

  • browser.ts ์ž‘์„ฑํ•˜๊ธฐ
    mocks/browser.ts : mocks ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ  ๊ทธ ์•ˆ์— browser.ts ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค. handlers๋ผ๋Š” ํŒŒ์ผ์„ ๋ฐ”๋กœ ๋‹ค์Œ์— ๋งŒ๋“ค๊ฑฐ๋‹ค. ์ด handlersํŒŒ์ผ์—๋Š” ์–ด๋–ค ์ฃผ์†Œ์˜ ์š”์ฒญ์— ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ผ์ง€ ๊ทœ์น™๋“ค์„ ๋ชจ์•„๋‘๋Š”๋ฐ, browser.ts๊ฐ€ ๊ฐ€์ ธ์˜จ ๊ทœ์น™๋“ค(hanlders)์„ ์„œ๋น„์Šค ์›Œ์ปค์— ์ฃผ์ž…ํ•˜์—ฌ ์‹ค์ œ ๊ฐ€์งœ ์„œ๋ฒ„ ์ธ์Šคํ„ด์Šค(worker)๋ฅผ ๋งŒ๋“ ๋‹ค. handlers ๋ฐฐ์—ด์— ๋‹ด๊ธด ์—ฌ๋Ÿฌ ๊ทœ์น™์„ ๊บผ๋‚ด์•ผํ•˜๋‹ˆ, ...(์ „๊ฐœ์—ฐ์‚ฐ์ž)๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

src๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ทธ ๋ฐ‘์— ๋งŒ๋“ค๋ฉด ๋œ๋‹ค

 

import { setupWorker } from 'msw/browser';
import { handlers } from './handlers';

export const worker = setupWorker(...handlers);
import { setupWorker } from 'msw/browser';๋Š” ๋ธŒ๋Ÿฌ์šฐ์ €์šฉ ์„œ๋น„์Šค ์›Œ์ปค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•ต์‹ฌ ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
import { handlers } from './handlers';๋Š” ์–ด๋–ค ์š”์ฒญ์„ ๋ณด๋‚ผ์ง€ ๊ทœ์น™์„ ๋ชจ์•„๋‘” ํŒŒ์ผ์ธ handlers ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜จ๋‹ค. 
export const worker = setupWorker(...handlers);๋Š” ๊ฐ€์ ธ์˜จ hanlders๋ฅผ ์„œ๋น„์Šค ์›Œ์ปค์— ์ฃผ์ž…ํ•˜์—ฌ ์‹ค์ œ ๊ฐ€์งœ ์„œ๋ฒ„ ์ธ์Šคํ„ด์Šค(worker)๋ฅผ ๋งŒ๋“ ๋‹ค. ...(์ „๊ฐœ์—ฐ์‚ฐ์ž)๋ฅผ ์‚ฌ์šฉํ•ด์„œ handlers ๋ฐฐ์—ด์— ๋‹ด๊ธด ์—ฌ๋Ÿฌ ๊ทœ์น™์„ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด์„œ ์„ค์ • ํ•จ์ˆ˜์— ์ „๋‹ฌํ•œ๋‹ค.

 

 

  • handler.ts ์ž‘์„ฑํ•˜๊ธฐ
    ์ด๊ฑด ๊ฐ์ž ์ฝ”๋“œ์— ๋งž์ถฐ์„œ ์ž‘์„ฑํ•ด์•ผํ•œ๋‹ค. ์ด ์ฝ”๋“œ๋ฅผ ๋” ์ž˜ ์ดํ•ดํ•˜๊ณ  ์‹ถ์œผ๋ฉด  [ํ–‰์šด์˜ ๋กœ๋˜ ๋งˆ๋ฒ•์ง„] ์นดํ…Œ๊ณ ๋ฆฌ๋กœ ๋“ค์–ด๊ฐ€์„œ "๊ตฌ์„ฑ"์„ ์ฝ์–ด๋ณด๋ฉด ๋„์›€์ด ๋  ๊ฒƒ์ด๋‹ค.
    a) ์ผ๋‹จ ์ด ํ”„๋กœ์ ํŠธ์˜ ๋ฉ”์ธํ™”๋ฉด์—๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋งˆ๋ฒ•์ง„์— ๋„ฃ์€ ์š”์†Œ๋“ค์„ 3๊ฐ€์ง€ ๊ณจ๋ผ์•ผํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ๊ทธ ์š”์†Œ๋ฅผ ๋ณด์—ฌ์ค„ ๋ถ€๋ถ„์„ ํ•ธ๋“ค๋Ÿฌ์— ์ž‘์„ฑํ•ด์•ผํ•œ๋‹ค. (์„ ํƒ ๋ชฉ๋ก ์ž‘์„ฑ : GET)
    b) ์‚ฌ์šฉ์ž๊ฐ€ 3๊ฐ€์ง€ ์„ ํƒ ์š”์†Œ๋ฅผ ๊ณ ๋ฅด๋ฉด ๋กœ๋˜ ์ถ”์ ์„ ์‹คํ–‰ํ•ด์•ผํ•œ๋‹ค. ์„ ํƒํ•œ ์˜ต์…˜์ด 3๊ฐ€์ง€์ธ์ง€ ํ™•์ธํ•˜๊ณ , ์•„๋‹ˆ๋ฉด ์—๋Ÿฌ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฒฐ๊ณผ๋ฌผ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. (๋กœ๋˜ ๋งˆ๋ฒ•์ง„ ์ƒ์„ฑ : POST)
import { http, HttpResponse } from 'msw';

// ์„ ํƒ์˜ต์…˜๋“ค
const optionItems = [
    'ํ–‰์šด',
    '์กฐ์ƒ๋‹˜์˜๋„์›€',
    '์ œ์™•์˜์ž๋ฆฌ',
    '๊ฐœ์ฉŒ๋Š”๊ฟˆ',
    '๋‚˜์˜์ง๊ฐ',
    '์—˜ํ”„์˜์„ ๊ฒฌ์ง€๋ช…',
    'ํ•œ์น˜์•ž์ด๋ณด์ด๋Š”๋‚ด์ธ์ƒ',
    '๋‚ด๋ˆ',
    '๋‹ค์ด์•„๋ชฌ๋“œ๊ด‘์‚ฐ์ฃผ์ธ',
    '๊ฐœ๊ฟˆ',
    '๋‚ด์ธ์ƒ์ˆ˜์ง์ƒ์Šนํ™ฉ๊ธˆํ‹ฐ์ผ“',
    '์š”์ •๋‹˜๋„์™€์ฃ ',
    '๋‚ด์ง‘๋งˆ๋ จ',
    '์™ธ๊ณ„์ธ์˜ํ…”๋ ˆํŒŒ์‹œ',
    'ํ‡ด์‚ฌ๊ฐ',
    '1๋“ฑ์ดํ•„์š”ํ•ด',
];

// ์š”์ฒญ ๋ฐ”๋”” ํƒ€์ž…
// POST ์š”์ฒญ ์‹œ ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ๋ณด๋‚ด์ค„ ๋ฐ์ดํ„ฐ์˜ ๊ทœ๊ฒฉ์„ TypeScript๋กœ ์ •์˜ํ–ˆ์Œ
type DrawRequestBody = {
    selectedOptions: string[];
};

export const handlers = [
    // ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ ํ™”๋ฉด์„ ๊ทธ๋ฆด ๋•Œ ํ•„์š”ํ•œ ์„ ํƒํ•  ์š”์†Œ๋“ค์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    // ๋‹จ์ˆœํžˆ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด๋ ค์ฃผ๋Š” ์ •์  ์‘๋‹ต์ด๋‹ˆ๊นŒ GET์œผ๋กœ...!
    http.get('/api/lotto/options', () => {
        return HttpResponse.json({
            options: optionItems,
        });
    }),

    // ๋กœ๋˜ ๋ฒˆํ˜ธ ์ถ”์ฒจ์„ ์‹คํ–‰ํ•œ๋‹ค.
    http.post('/api/lotto/draw', async ({ request }) => {
        // request.json์„ ํ†ตํ•ด ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ๋ณด๋‚ธ JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜จ๋‹ค.
        const body = (await request.json()) as Partial<DrawRequestBody>;
        const selectedOptions = body.selectedOptions ?? [];

        // ์š”์†Œ 3๊ฐ€์ง€๋ฅผ ์„ ํƒํ•˜์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ 400 Bad Request ์—๋Ÿฌ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
        if (selectedOptions.length !== 3) {
            return HttpResponse.json(
                {
                    message: '์š”์†Œ 3๊ฐ€์ง€๋ฅผ ์„ ํƒํ•ด์ฃผ์„ธ์š”.',
                },
                { status: 400 }
            );
        }

        // 3๊ฐœ๋ฅผ ์ œ๋Œ€๋กœ ์„ ํƒํ–ˆ๋‹ค๋ฉด ๋กœ๋˜ ๋ฒˆํ˜ธ์™€ ํ–‰์šด์˜ ์ ์ˆ˜, ์ด๋ฏธ์ง€ ๊ฒฝ๋กœ ๋“ฑ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
        // ์›๋ž˜๋Š” ํ–‰์šด์˜ ์ ์ˆ˜, ๋ฉ”์‹œ์ง€๋Š” ๊ณ„์‚ฐ ๋กœ์ง์— ์˜ํ•ด ๋‚˜ํƒ€๋‚˜์•ผํ•˜๋Š”๋ฐ,
        // ์ง€๊ธˆ์€ ํ…Œ์ŠคํŠธ ๊ณผ์ •์ด๋‹ˆ๊นŒ ์–ด๋–ค ๊ฑธ ์„ ํƒํ•˜๋Š” ์•„๋ž˜ ์„ค์ •ํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜ํƒ€๋‚œ๋‹ค.
        return HttpResponse.json({
            numbers: [3, 11, 19, 27, 34, 42],
            luckScore: 84,
            luckMessage: '์šฐ์ฃผ ํ†ต์‹  ์—ฐ๊ฒฐ ์™„๋ฃŒ',
            selectedOptions,
            spellNumber: 3,
            spellImageUrl: '/images/spells/3.png',
        });
    }),
];

 

 

 


 

 

 

 

5. ํ”„๋ก ํŠธ ์ฝ”๋“œ ์‚ดํŽด๋ณด๊ธฐ - MSW๋ž‘ ์—ฐ๊ฒฐํ•ด์„œ

  • HomePage.tsx(๋ฉ”์ธํŽ˜์ด์ง€)_ ์š”์ฒญ ๋ณด๋‚ด๊ธฐ

                   <button
                        type="button"
                        className={styles.createButton}
                        onClick={handleCreateClick}
                        disabled={isSubmitting}
                    >
์ฟต์ง์ฟต์ง ๋งŒ๋“ค๊ธฐ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ handleCreateClick์ด๋ผ๊ณ  ์ •ํ–ˆ๋‹ค.

 

    // ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์ด์ œ ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ์˜์ฐจ์˜์ฐจ ๋Œ์•„๊ฐ„๋‹ค.
    const handleCreateClick = async () => {
    
        // ์š”์†Œ 3๊ฐ€์ง€๋ฅผ ์„ ํƒํ–ˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
        if (selectedOptions.length !== 3) {
            showMagicToast('์š”์†Œ 3๊ฐ€์ง€๋ฅผ ์„ ํƒํ•ด์ฃผ์„ธ์š”.');
            return;
        }

        try {
            setIsSubmitting(true);
            
            // ์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด fetch๊ฐ€ ์‹คํ–‰๋œ๋‹ค.
            // ์›๋ž˜๋ผ๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ์ง„์งœ ์„œ๋ฒ„ ์ฃผ์†Œ๋ฅผ ์ฐพ์•„ ๋‚˜๊ฐ„๋‹ค.
            // ๊ทธ๋Ÿฐ๋ฐ MSW๊ฐ€ ์ด ์š”์ฒญ์„ ์ค‘๊ฐ„์—์„œ ๋‚š์•„์ฑˆ๋‹ค.
            const response = await fetch('/api/lotto/draw', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    selectedOptions,
                }),
            });

            // MSW๊ฐ€ ์ค€ ๊ฐ€์งœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•˜๋‹ค.
            // result ๋ณ€์ˆ˜์—๋Š” ํ•ธ๋“ค๋Ÿฌ์— ์ ์–ด๋‘์—ˆ๋˜ ๋กœ๋˜ ๋ฒˆํ˜ธ, ํ–‰์šด ์ ์ˆ˜ ๋“ฑ์ด ๋‹ด๊ธด๋‹ค.
            const result: DrawResponse = await response.json();
            
            // ๋‹น์žฅ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ฃผ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ๊ณผ๊ฐ’์„ sessionStorage์— ๋ณด๊ด€ํ•œ๋‹ค.
            // ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋‹ซํžˆ๊ธฐ ์ „๊นŒ์ง€ ๋ณด๊ด€์€ ์œ ์ง€๋œ๋‹ค.
            sessionStorage.setItem('lotto-result', JSON.stringify(result));
            
            // ๊ทธ ํ›„ ๋กœ๋”ฉํŽ˜์ด์ง€๋กœ ๋„˜์–ด๊ฐ„๋‹ค.
            router.push('/loading');

 

 

  • ResultPage.tsx(๊ฒฐ๊ณผํŽ˜์ด์ง€)_ ์„ธ์…˜์Šคํ† ๋ฆฌ์ง€์— ์žˆ๋Š” ๊ฒฐ๊ณผ ๋ณด์ด๊ธฐ

    useEffect(() => {
        const savedResult = sessionStorage.getItem('lotto-result');

 

 

์•„๊นŒ HomePage.tsx์—์„œ sessionStorage์— ๊ฒฐ๊ณผ๊ฐ’์„ ์ €์žฅํ•ด๋’€๋‹ค. ๊ทธ ์ €์žฅํ•ด๋‘” ๊ฐ’์„ ๊ฐ€์ ธ์™€์„œ ํ™”๋ฉด์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

 

 

 


 

- MSW (React+TypeScript) ์„ค์น˜

 

React์—์„œ MSW ์‚ฌ์šฉํ•˜๊ธฐ

์˜ค๋Š˜์€ ์ด์ง์„ ์ค€๋น„ํ•˜๋ฉด์„œ ๊ณผ์ œ ์ „ํ˜•์—์„œ ์ฒ˜์Œ ๋‹ค๋ค„๋ณด์•˜๋˜ msw๋ผ๋Š” ๊ฒƒ์„ ์•Œ์•„๋ณด์ž.๊ณผ์ œ ์ „ํ˜•์„ ๋ฐ›์•˜์„๋•Œ ๊ธฐ์ดˆ ํ…œํ”Œ๋ฆฟ๊ณผ ๊ณผ์ œ ์„ค๋ช…์ด ๋“ค์–ด๊ฐ„ ํ…œํ”Œ๋ฆฟ์„ ๋ฐ›์•˜๋Š”๋ฐ, ์ œ์ผ ๋‹นํ™ฉํ–ˆ๋˜ ๋ถ€๋ถ„์€ api์˜ end-po

velog.io

 

 

- MSW์˜ ์„ค๋ช…๊ณผ ์„ค์น˜

 

MSW(Mock Service Worker)๋กœ ๋”์šฑ ์ƒ์‚ฐ์ ์ธ FE ๊ฐœ๋ฐœํ•˜๊ธฐ

MSW(Mock Service Worker)๋Š” Service Worker๋ฅผ ์ด์šฉํ•ด ์„œ๋ฒ„๋ฅผ ํ–ฅํ•œ ์‹ค์ œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„์„œ(intercept) ๋ชจ์˜ ์‘๋‹ต (Mocked response)๋ฅผ ๋ณด๋‚ด์ฃผ๋Š” API Mocking ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

velog.io