리액트 공식문서 - 틱택토 게임

2026. 2. 11. 16:57·web/react

intro

 

이번 시간에는 리액터 공식문서 초반 페이지에 있는 틱택토 게임을 만들어 보고, 학습한 내용을 정리해보겠습니다.



1. full code

 

import { useState } from "react";

function Square({ value, onSquareClick }) {
  return (
    <button className="square" onClick={onSquareClick}>
      {value}
    </button>
  );
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}

export default function Board() {
  const [xIsNext, setXIsNext] = useState(true);
  const [squares, setSquares] = useState(Array(9).fill(null));

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = "Winner: " + winner;
  } else {
    status = "Next player: " + (xIsNext ? "X" : "O");
  }

  function handleClick(i) {
    if (squares[i] || calculateWinner(squares)) {
      // 애초에 square에 값이 있으면 || 승자가 정해졌다면 =>  조기리턴
      return;
    }
    const nextSquares = squares.slice();
    if (xIsNext) {
      nextSquares[i] = "X";
    } else {
      nextSquares[i] = "O";
    }
    setSquares(nextSquares);
    setXIsNext(!xIsNext);
  }

  return (
    <>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
      <div className="status">{status}</div>
    </>
  );
}

 

 

2. 주요 핵심개념

  • 컴포넌트 재사용성: Square라는 작은 단위의 컴포넌트를 만들어 Board에서 9번 재사용
  • State 끌어올리기: 각 사각형의 상태를 Square가 직접 가지지 않고, 부모 컴포넌트인 Board에서 관리하게 함으로써 데이터의 일관성을 유지했음
  • 불변성 지키기: 배열의 값을 직접 수정x, squares.slice()를 사용하여 기존 배열을 직접 수정하지 않고 복사본을 만들어 업데이트함.

 


3. 코드 분석하기

 

Square 컴포넌트

- value를 받아 화면에 표시하고, 클릭 시 부모로부터 받은 onSquareClick 함수를 실행

 

 

calcualteWinner(승리에 관한 로직)

- 8가지 승리 조합(가로, 세로, 대각선)을 미리 정의해두고, 현재 squares 상태와 비교하여 승자를 판별함.

 

 

handleClick (게임 제어 관련 로직)

- 조기리턴: 이미 값이 있거나 승자가 결정되었다면 클릭을 무시

- 상태 업데이트: 현재 턴에 맞춰 배열을 업데이트하고 다음 턴으로 넘김

 


전체 코드 flow 요약

 

1. 사용자가 Square를 클릭

2. Board의 handleClick함수가 호출됨

3. squares배열의 복사본을 만들어 해당 인덱스에 x또는 o를 채움

4. setSAquares와 setXIsNext로 상태를 업데이트함

5. 상태가 변했으므로 화면이 다시 그려지고, 승리 여부를 체크

 

 


 

틱택토 만들기를 마치며,,

 

리액트에서 배열을 복사해서 써야 한다는 개념이 때로는 낯설었지만, 리액트의 렌더링 원리를 이해하는 데 큰 도움이 되었고, 여러가지 로직과 props, state, 변수의 현재 상태 등의 개념을 학습하면서 리액트의 기초에 대해 많이 배워가는 느낌이었습니다. 

다음시간에도 리액트 공부로 돌아오겠습니다~

저작자표시 (새창열림)

'web > react' 카테고리의 다른 글

리액트 Context에 대해 알아보고 다크모드를 만들어보자! (feat: custom hook)  (0) 2026.03.30
리액트에서 왜 불변성을 지켜야 할까?  (0) 2026.03.13
useRef는 어떻게 데이터를 변화시키지 않을 수 있을까?  (0) 2026.02.27
리액트 공식문서 과제 오답노트  (0) 2026.02.19
리액트 기본 - 공식문서 리딩  (0) 2026.02.11
'web/react' 카테고리의 다른 글
  • 리액트에서 왜 불변성을 지켜야 할까?
  • useRef는 어떻게 데이터를 변화시키지 않을 수 있을까?
  • 리액트 공식문서 과제 오답노트
  • 리액트 기본 - 공식문서 리딩
noeyh
noeyh
기록하고 성장하는 개발자, 최유현 입니다. github : https://github.com/Choiyuhyeon
    티스토리 홈 로그아웃
  • noeyh
    CreateU
    noeyh
  • 전체
    오늘
    어제
  • 글쓰기 관리
    GitHub
    Notion
    • 분류 전체보기 (31)
      • web (22)
        • html (5)
        • css (4)
        • js (5)
        • react (6)
        • next (1)
      • server (0)
      • linux (0)
      • figma (0)
      • ml (0)
      • algorithm (5)
      • git (1)
      • 미니프로젝트 (0)
      • 프로젝트 (0)
      • 정보 (0)
      • 일상 (0)
      • memo (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • hELLO· Designed By정상우.v4.10.6
noeyh
리액트 공식문서 - 틱택토 게임
상단으로

티스토리툴바