React 코딩 챌린지: 카드 플립 게임

발행: (2026년 1월 1일 오후 01:49 GMT+9)
2 min read
원문: Dev.to

Source: Dev.to

React 카드 뒤집기 게임 – 코드

import "./styles.css";
import React, { useState, useEffect } from "react";

const values = [1, 2, 3, 4, 5];

type Card = {
  id: number;
  value: number;
  isFlipped: boolean;
  isMatched: boolean;
};

function getShuffledCards(): Card[] {
  const deck = [...values, ...values].map((value, index) => ({
    id: index,
    value,
    isFlipped: false,
    isMatched: false,
  }));

  // Shuffle
  return deck.sort(() => Math.random() - 0.5);
}

export default function App() {
  const [cards, setCards] = useState(getShuffledCards);
  const [selected, setSelected] = useState([]);

  useEffect(() => {
    if (selected.length !== 2) return;

    const [first, second] = selected;
    const card1 = cards[first];
    const card2 = cards[second];

    if (card1.value === card2.value) {
      setCards((prev) =>
        prev.map((card, i) =>
          i === first || i === second ? { ...card, isMatched: true } : card
        )
      );
      setSelected([]);
    } else {
      // flip back after delay
      setTimeout(() => {
        setCards((prev) =>
          prev.map((card, i) =>
            i === first || i === second ? { ...card, isFlipped: false } : card
          )
        );
        setSelected([]);
      }, 800);
    }
  }, [selected, cards]);

  const handleCardClick = (index: number) => {
    if (
      cards[index].isFlipped ||
      cards[index].isMatched ||
      selected.length === 2
    )
      return;

    setCards((prev) =>
      prev.map((card, i) => (i === index ? { ...card, isFlipped: true } : card))
    );

    setSelected((prev) => [...prev, index]);
  };

  return (
    
      
        {cards.map((card, index) => (
           handleCardClick(index)}
          >
            
              {card.isFlipped || card.isMatched ? card.value : "?"}
            
          
        ))}
      
    
  );
}

스타일

.App {
  font-family: sans-serif;
  padding: 20px;
}

.grid {
  display: grid;
  grid-template-columns: repeat(4, 80px);
  gap: 12px;
  justify-content: center;
}

.card {
  width: 80px;
  height: 80px;
  background: #2c3e50;
  color: white;
  font-size: 24px;
  cursor: pointer;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  user-select: none;
  transition: transform 0.3s, background 0.3s;
}

.card.flipped {
  background: #27ae60;
  transform: scale(1.05);
}

.card-inner {
  font-weight: bold;
}

카드 뒤집기 게임 스크린샷

Back to Blog

관련 글

더 보기 »

React 코딩 챌린지 : TIC-TAC-TOE

React 틱택토 구현 컴포넌트 코드 javascript import { useState } from 'react'; import './styles.css'; function Square{ value, onClick } { return...