
react 튜토리얼 중에 가장 유명한 Tic-Tac-Toe를 만들면서 실습을 해보았다.
// index.js const render = () => { const element = ( <div> <TicTacToc></TicTacToc> </div> ); root.render(element); }; render();
// TicTacToc.js import { useState } from "react"; import Board from "./Board"; export default function TicTacToc() { const [history, setHistory] = useState([Array(9).fill(null)]); const [currentMove, setCurrentMove] = useState(0); const xIsNext = currentMove % 2 === 0; const currentSquares = history[currentMove]; const handlePlay = (nextSquares) => { const nextHistory = [...history.slice(0, currentMove + 1), nextSquares]; setHistory(nextHistory); setCurrentMove(nextHistory.length - 1); } function jumpTo(nextMove) { setCurrentMove(nextMove); } const moves = history.map((squares, move) => { let description; if (move > 0) { description = 'Go to move #' + move; } else { description = 'Go to game start'; } return ( <li key={move}> <button onClick={() => jumpTo(move)}>{description}</button> </li> ); }); return ( <div className="game"> <div className="game-board"> <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} /> </div> <div className="game-info"> <ol>{moves}</ol> </div> </div> ); }
import Square from "./Square"; export default function Board({ xIsNext, squares, onPlay }) { const handleClick = (i) => { if (calculateWinner(squares) || squares[i]) { return; } const nextSquares = squares.slice(); if (xIsNext) { nextSquares[i] = "X"; } else { nextSquares[i] = "O"; } onPlay(nextSquares); } const 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; } const winner = calculateWinner(squares); let status; if (winner) { status = "Winner: " + winner; } else { status = "Next player: " + (xIsNext ? "X" : "O"); } return (<> <div className="status">{status}</div> <div className="board-row"> <Square value={squares[0]} onSquareClick={() => handleClick(0)}></Square> <Square value={squares[1]} onSquareClick={() => handleClick(1)}></Square> <Square value={squares[2]} onSquareClick={() => handleClick(2)}></Square> </div> <div className="board-row"> <Square value={squares[3]} onSquareClick={() => handleClick(3)}></Square> <Square value={squares[4]} onSquareClick={() => handleClick(4)}></Square> <Square value={squares[5]} onSquareClick={() => handleClick(5)}></Square> </div> <div className="board-row"> <Square value={squares[6]} onSquareClick={() => handleClick(6)}></Square> <Square value={squares[7]} onSquareClick={() => handleClick(7)}></Square> <Square value={squares[8]} onSquareClick={() => handleClick(8)}></Square> </div> </>) }
export default function Square({ value, onSquareClick }) { return ( <button className="square" onClick={onSquareClick}>{value}</button>) }
다 만들고나니깐 맨 아래에 5가지의 개선사항에 도전해보라는 말이 있었다.
5가지의 개선사항에 대해서 수정해보며, 똑같은 게임을 vue의 composition API로도 한번 구현해봐야겠다.
잘 봤습니다. 좋은 글 감사합니다.