[React] TicTacToe앱 만들기(1) - 컴포넌트 생성, props, state

2024. 6. 14. 00:04·React
728x90

1. 기본 설정

택택톡 앱은 크게 게임판 부분과 게임 정보 부분으로 구성된다.

App.js

function App() {
  return (
    <>
      <div className="game">
        <div className="game-board">

        </div>
        <div className="game-info">

        </div>
      </div>
    </>
  );
}

export default App;

 

App.css

.game{
  display: flex;
  flex-direction: row;
}

.game-info {
  margin-left: 20px;
}

 

index.css

body {
  font: 14px "Century Gothic", Futura, sans-serif;
  margin: 20px;
}

ol, ul {
  padding-left: 30px;
}

 

2. Board, Square 컴포넌트 생성

컴포넌트 폴더를 생성하고 그 안에 Board와 Square 컴포넌트를 생성한다.

Reactjs Code Snippet 확장 프로그램을 설치했다면 단축어로 컴포넌트 코드를 간편하게 생성할 수 있다.

함수형 컴포넌트는 rsc, 클래스형 컴포넌트는 rcc을 입력하면 된다.

import React, { Component } from 'react';

class Board extends Component {
  render() {
    return (
      <div>
       
      </div>
    );
  }
}

export default Board;
import React, { Component } from 'react';

class Square extends Component {
  render() {
    return (
      <div>
       
      </div>
    );
  }
}

export default Square;

 

Square.js는 board를 구성하는 각 칸이고 각 칸은 버튼으로 만든다.

class Square extends Component {
  render() {
    return (
      <button className='square'>
        Square
      </button>
    );
  }
}

 

Board.js에서 Square를 연결하는데 Square 컴포넌트를 바로 연결하지 않고, Square를 리턴하는 함수를 만들어서 그 함수를 호출하도록 한다. 함수는 몇번째 Square인지를 인자로 받는다.

0 1 2
3 4 5
6 7 8
class Board extends Component {
  renderSquare(i) {
    return <Square />
  }
  render() {
    return (
      <div>
        <div className="status">Next Player: X, O</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>
    )
  }
}

 

이제 App.js에 Board 컴포넌트를 연결한다.

function App() {
  return (
    <>
      <div className="game">
        <div className="game-board">
          <Board />
        </div>
        <div className="game-info">
          game-info
        </div>
      </div>
    </>
  );
}

 

Board, Square 스타일링)

각각의 파일에서 css파일을 import한다.

import "./Board.css";
import "./Square.css";

 

Square.js

.square {
  background-color: #fff;
  border: 1px solid #999;
  font-size: 24px;
  height: 34px;
  margin-right: -1px;
  margin-top: -5px;
  padding: 0;
  text-align: center;
  width: 34px;
}

 

Board.js

.status {
  margin-bottom: 10px;
}

 

3. 데이터 전달(Props)

board컴포넌트에서 square컴포넌트로 칸 번호를 넘겨준다. props를 렌더링할 때는 JSX에서 {}로 감싸주면 된다.

class Board extends Component {
  renderSquare(i) {
    return <Square value={i} />
  }
class Square extends Component {
  render() {
    return (
      <button className='square'>
        {this.props.value}
      </button>

props는 부모 컴포넌트에서만 설정이 가능하며 컴포넌트 자신은 props를 읽기 전용으로만 사용할 수 있다.

 

4. State 추가

state는 컴포넌트 내부에서 바뀔 수 있는 값이다. state가 변경되면 컴포넌트는 리렌더링되며 state는 컴포넌트 안에서 관리된다.

컴포넌트에 state를 설정할 때는 constructor메서드를 작성하여 설정하며, 클래스형 컴포넌트에서 constructor를 작성할 때는 super(porps)를 호출해야 한다.

class Square extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: null
    }
  }
  render() {
    return (
      <button className='square' onClick={() => console.log('click')}>
        {this.state.value}
      </button>
    );
  }
}

이렇게 하면 칸의 값은 null이므로 아무것도 안보이게 된다.

칸을 클릭하면 X가 나타나도록 setState를 사용해 state 값을 업데이트한다.

<button className='square' onClick={() => this.setState({ value: 'X' })}>

 

여러 자식으로부터 데이터를 받거나 두 자식이 서로 통신하도록 하려면 부모 컴포넌트에 공유 state를 정의해야 한다. 부모 컴포넌트는 props를 사용해 자식 컴포넌트에 state를 다시 전달할 수 있고, 이는 자식 컴포넌트들이 서로 또는 부모 컴포넌트와 동기화하도록 만든다.

위에서 추가한 state를 부모 컴포넌트인 Board.js로 옮긴다. 9칸의 사각형에 해당하는 길이가 9인 배열을 초기 state로 설정한다.

class Board extends Component {
  constructor(props) {
    super(props);
    this.state = {
     squares: Array(9).fill(null)
    }
  }

renderSquare 메서드는 Squares 배열의 인덱스를 반환하도록 한다.

  renderSquare(i) {
    return <Square value={this.state.squares[i]} />
  }

Square 컴포넌트에서 state를 삭제했으므로 this.state를 this.props로 수정한다.

class Square extends Component {
  render() {
    return (
      <button className='square' onClick={() => this.setState({ value: 'X' })}>
        {this.props.value}
      </button>
    );
  }
}

 

Board 컴포넌트에 square값을 'X'로 바꾸는 함수를 추가한다.

  handleClick(i) {
    const squares = this.state.squares.slice();
    squares[i] = 'X';
    this.setState({ squares: squares })
  }


스퀘어 값을 반환하는 renderSquare 메서드에서 클릭하면 handleClick 메서드를 호출하도록 한다.

  renderSquare(i) {
    return <Square value={this.state.squares[i]} onClick={() => this.handleClick(i)} />
  }

 

class Square extends Component {
  render() {
    return (
      <button className='square' onClick={() => { this.props.onClick() }}>
        {this.props.value}
      </button>
    );
  }
}

 

  1. 버튼을 클릭하면 onClick 이벤트 핸들러를 호출하고 이벤트 핸들러는 this.props.onClick()을 호출한다.
  2. Board에서 Square로 onClick={() => this.handleClick(i)}를 전달하기 때문에 Square를 클릭하면 Board의 handleClick(i)를 호출한다.

728x90

'React' 카테고리의 다른 글

[React / Gsap] 스크롤과 터치에 따른 애니메이션 전환 효과 구현  (1) 2024.09.27
[React] TicTacToe앱 만들기(3) - 게임 동작 기록, jumpTo()  (0) 2024.06.20
[React] TicTacToe앱 만들기(2) - 리액트 Hooks, 순서, 승자 판별  (0) 2024.06.18
[React] 번들러 | 리액트 컴포넌트 | JSX  (0) 2024.06.12
[React] 리액트 프로젝트 생성(create-react-app)  (1) 2024.06.12
'React' 카테고리의 다른 글
  • [React] TicTacToe앱 만들기(3) - 게임 동작 기록, jumpTo()
  • [React] TicTacToe앱 만들기(2) - 리액트 Hooks, 순서, 승자 판별
  • [React] 번들러 | 리액트 컴포넌트 | JSX
  • [React] 리액트 프로젝트 생성(create-react-app)
gamzaggang7
gamzaggang7
    250x250
  • gamzaggang7
    abcdefghklpqrstuvwxyz
    gamzaggang7
  • 전체
    오늘
    어제
    • 분류 전체보기
      • CS
        • OS
        • 자료구조_알고리즘
      • Java
      • Javascript
      • Node.js
      • React
      • Vue.js
      • 코딩테스트
        • 백준-Java
        • 프로그래머스-JS
      • Canvas
      • HTML, CSS
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

    dat.gui
    자바
    vue.js
    백준풀이
    스택
    프로그래머스
    css
    라우팅
    큐
    Next.js
    자바백준풀이
    props
    npm
    BFS
    Node.js
    fegaussianblur
    canvas
    2차원배열
    자바공부
    정렬
    fecolormatrix
    React
    오즈코딩스쿨
    hashchange
    vue animation
    til
    자바스크립트
    vue modal
    서버구축
    해시
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
gamzaggang7
[React] TicTacToe앱 만들기(1) - 컴포넌트 생성, props, state
상단으로

티스토리툴바