React Docs 단계별 가이드 정리 2. Tic-Tac-Toe_1

남예지·2023년 5월 29일
0

React

목록 보기
3/6

Tic-Tac-Toe

작은 Tic-Tac-Toe 게임을 만든다고 한다. (Do근Do근)

참고 사이트 : https://react.dev/learn/tutorial-tic-tac-toe#setup-for-the-tutorial

1. 여기서 튜토리얼 설정에 있는 APP.JS를 fork해서 시작한다.

export default function Square() {
  return <button className="square">X</button>;
}

export default function Square() 은 Square함수를 정의한다.
export 키워드는 이 파일 외부에서 이 기능에 엑세스 할 수 있도록 한다.
default는 코드를 사용하여 파일의 주요 기능임을 다른 파일에게 알린다.

return <button className="square">X</button> 은 버튼을 반환한다.
<button>은 JSX 요소이다.

2. 이제 이 박스를 9개 만든다.

9개를 만들면 박스가 한줄로 쭉 놓이는데 div 태그로 3개씩 묶어주고, div 태그 안에 'board-row'라는 className을 준다.

styles.css에 이미 스타일이 정의되어 있어서 결과물은 아래와 같다.

export default function Board() {
  return (
    <>
      <div className="board-row">
        <button className="square">1</button>
        <button className="square">2</button>
        <button className="square">3</button>
      </div>
      <div className="board-row">
        <button className="square">4</button>
        <button className="square">5</button>
        <button className="square">6</button>
      </div>
      <div className="board-row">
        <button className="square">7</button>
        <button className="square">8</button>
        <button className="square">9</button>
      </div>
    </>
  );
}

3. 소품을 통한 데이터 전달

사용자가 사각형을 클릭 시 값을 빈 값에서 'X'로 변경하려 한다.

App.js에 Square 컴포넌트를 만들고 이를 Board 컴포넌트에서 렌더링하도록 불러온다.

function Square() {
  return <button className="square">1</button>;
}

export default function Board() {
  return (
    <>
      <div className="board-row">
        <Square />
        <Square />
        <Square />
      </div>
      <div className="board-row">
        <Square />
        <Square />
        <Square />
      </div>
      <div className="board-row">
        <Square />
        <Square />
        <Square />
      </div>
    </>
  );
}

다시 1~9가 세겨진 board를 원한다면 1 대신 value를 지정해 props해준다.

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

export default function Board() {
  return (
    <>
      <div className="board-row">
        <Square value="1" />
        <Square value="2" />
        <Square value="3" />
      </div>
      <div className="board-row">
        <Square value="4" />
        <Square value="5" />
        <Square value="6" />
      </div>
      <div className="board-row">
        <Square value="7" />
        <Square value="8" />
        <Square value="9" />
      </div>
    </>
  );
}

4. 대화형 구성 요소 만들기

우선 클릭 시 내부에 x가 호출되는 함수를 선언한다.
우선 첫번째로 클릭 이벤트 핸들러를 만들고 버튼에 적용한다.
그리고 클릭된 것을 기억하고 x로 채우기 위해 useState를 사용한다.
Board에 Square vlaue는 지워준다.

import { useState } from "react";

function Square() {
  const [value, setValue] = useState(null);

  function handleClick() {
    setValue('X')
  }
  return (
    <button className="square" onClick={handleClick}>
      {value}
    </button>
  );
}

클릭 이벤트 시 setValue('x') 가 실행된다.

5. o, x가 번갈아 나오게 하기

완전한 게임을 하려면 이제 보드에 "X"와 "O"를 번갈아 배치해야 하며 승자를 결정하는 방법이 필요하다.

이번에는 상태관리가 Board 컴포넌트에 의해 처리되게끔 해보자.
코드는 아래와 같다.

import { useState } from "react";

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

export default function Board() {
  const [squares, setSquares] = useState(Array(9).fill(null));
  function handleClick(i) {
    const nextSquares = squares.slice();
    nextSquares[i] = "X";
    setSquares(nextSquares);
  }
  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>
    </>
  );
}

이제 X를 클릭하여 보드의 모든 사각형에 X를 다시 추가할 수 있다.
이때 발생하는 일을 요약하면 다음과 같다.

  1. 왼쪽 위 사각형을 클릭하면 단추가 Square에서 onClick prop으로 받은 함수가 실행된다. Square 컴포넌트는 Board에서 onSquareClick 소품으로 해당 기능을 받는다. Board 컴포넌트는 JSX에서 직접 해당 기능을 정의하고 0 인수로 handleClick을 호출한다.
  2. handleClick은 인수(0)를 사용하여 사각형 배열의 첫 번째 요소를 null에서 X로 업데이트한다.
  3. Board 컴포넌트의 사각형 상태가 업데이트되었으므로 Board와 모든 자식이 다시 렌더링된다. 이로 인해 인덱스가 0인 Square 컴포넌트의 value prop이 null에서 X로 변경된다.

너무 길어서 1,2로 나눠야겠다.

profile
총총

0개의 댓글