๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
TIL -์ผ๊ฐ„ํ•™์Šต๊ธฐ๋ก/React

[React ์ž์Šต์„œ] Tic Tac Toe..

by ___Jin 2022. 2. 3.

ํˆฌ๋‘๋ฆฌ์ŠคํŠธ๋ฅผ ์‹œ์ž‘ ํ•˜๊ธฐ์— ์•ž์„œ ๋ฆฌ์•กํŠธ๋ฅผ ๋„ˆ๋ฌด ๋ชจ๋ฅด๋Š”๊ฑฐ ๊ฐ™์•„, ๊ณต์‹๋ฌธ์„œ ์ž์Šต์„œ์˜ ํ‹ฑํƒํ† ๋ฅผ ๊ณต๋ถ€ํ•˜๊ณ ์žˆ๋‹ค.

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

class Board extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      squares: Array(9).fill(null),
      xIsNext : true,
    };
  }
  
  handleClick(i) {
    const squares = this.state.squares.slice();
    if(calculateWinner(squares) || squares[i]){
      return;
    }
    squares[i] = this.state.xIsNext ? 'X' : 'O';
    this.setState({
      squares: squares,
      xIsNext : !this.state.xIsNext,
    });
  }
  
  renderSquare(i) {
    return (
      <Square 
        value ={this.state.squares[i]} 
        onClick ={ () => this.handleClick(i)}
      />
    );
  }

  render() {
    const winner = calculateWinner(this.state.squares);
    let status;
    if (winner) {
      status = 'Winner : '+ winner;
    } else {
      status = 'Next player : ' + (this.state.xIsNext ? 'X' : 'O');
    }
    

    return (
      <div>
        <div className="status">{status}</div>
        <div className="board-row">
          {this.renderSquare(0)}
          {this.renderSquare(1)}
          {this.renderSquare(2)}
        </div>
        <div className="board-row">
          {this.renderSquare(3)}
          {this.renderSquare(4)}
          {this.renderSquare(5)}
        </div>
        <div className="board-row">
          {this.renderSquare(6)}
          {this.renderSquare(7)}
          {this.renderSquare(8)}
        </div>
      </div>
    );
  }
}

class Game extends React.Component {
  render() {
    return (
      <div className="game">
        <div className="game-board">
          <Board />
        </div>
        <div className="game-info">
          <div>{/* status */}</div>
          <ol>{/* TODO */}</ol>
        </div>
      </div>
    );
  }
}

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;
}

// ========================================

ReactDOM.render(
  <Game />,
  document.getElementById('root')
);

props์™€ state๊ฐ€ ํ—ท๊ฐˆ๋ ค์„œ ๊ณต๋ถ€์ค‘์ธ๋ฐ, 

๋ณ€์ˆ˜๋ช…์œผ๋กœ ์ ํ˜€์žˆ์œผ๋ฉด ์ข‹์„ํ…๋ฐ props์™€ state๋กœ ์ ํ˜€์žˆ์–ด ๋”ํ—ท๊ฐˆ๋ฆฐ๋‹ค.

handleClick(i)ํ•จ์ˆ˜ ๋ถ€๋ถ„์˜ ๋กœ์ง์ด ์ž˜์ดํ•ด๊ฐ€ ๊ฐ€์ง€์•Š์•„์„œ ๋ณด๊ณ  ๋˜ ๋ณด๊ณ  ๊ณ„์† ๋Œ๋ ค๋ณด๊ณ ์žˆ๋‹ค.

๋ชจ๋ฅด๋Š” ๋ถ€๋ถ„์€ ์—ฌ๊ธฐ์„œ state์™€ props์˜ ๊ฐ’์ด ๋ฌด์—‡์ธ๊ฐ€ ์ด๋‹ค.

๋‘๊ฐ€์ง€๊ฐ€ ํ™•์‹คํ•˜์ง€์•Š์•„์„œ ๋‘๋ฃจ๋ญ‰์‹คํ•˜๋‹ค.

๋‘๊ฐ€์ง€๋ฅผ ์ •๋ฆฌํ•˜๊ณ  ๊ฐ€์•ผํ• ๊ฒƒ ๊ฐ™๋‹ค.

 

Props VS State

 

๊ณตํ†ต์  :

๊ฐ„๋‹จํ•˜๊ฒŒ๋Š” ๋‘˜๋‹ค ํ˜„์žฌํ™”๋ฉด์— ๋ณด์ด๋Š” ๊ฐ’์„ ๋งํ•œ๋‹ค.

๋˜ํ•œ ์ผ๋ฐ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด๋กœ ๋‘๊ฐ์ฒด ๋ชจ๋‘ ๋ Œ๋”๋ฆฐ ๊ฒฐ๊ณผ๋ฌผ์— ์˜ํ–ฅ์„ ์ค€๋‹ค.

๋ถ€๋ชจ๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ props ๋ฐ state ์ดˆ๊ธฐ๊ฐ’์€ ๋ชจ๋‘ Component ๋‚ด๋ถ€์— ์ •์˜๋œ ๊ธฐ๋ณธ๊ฐ’์„ ์žฌ์ •์˜ํ•œ๋‹ค.

 

์ฐจ์ด์ 

props = ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌ๋˜๋ฉฐ, ์ปดํฌ๋„ŒํŠธ์˜ render()ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ์ด๋‹ค.

(๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋””์„œ ์™”๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.)

 

state = ํ•จ์ˆ˜๋‚ด์— ์„ ์–ธ๋œ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์ปดํฌ๋„ŒํŠธ์•ˆ์—์„œ ๊ด€๋ฆฌ๋œ๋‹ค.

props์™€ state๋ฅผ ๋น„๊ตํ•œ ํ‘œ

์ •๋ฆฌ๋ฅผ ํ•˜๋ฉด ์•Œ๊ฒ ๋Š”๋ฐ ๋ง‰์ƒ ์ฝ”๋“œ์—์„œ ๋งž๋‹ฅ๋œจ๋ฆฌ๋ฉด ํ—ท๊ฐˆ๋ฆฐ๋‹ค. 

๊ณ„์† ๋ณด๋ฉด์„œ ์ต์ˆ™ํ•ด ์ ธ์•ผํ• ๊ฒƒ ๊ฐ™๋‹ค.

๋Œ“๊ธ€