작은 Tic-Tac-Toe 게임을 만든다고 한다. (Do근Do근)
참고 사이트 : https://react.dev/learn/tutorial-tic-tac-toe#setup-for-the-tutorial
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 요소이다.
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>
</>
);
}
사용자가 사각형을 클릭 시 값을 빈 값에서 '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>
</>
);
}
우선 클릭 시 내부에 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') 가 실행된다.
완전한 게임을 하려면 이제 보드에 "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,2로 나눠야겠다.