본문 바로가기

React + React Native + Expo

[React 연습 1일차] 리액트 TicTacToe Game 구현

반응형

 

처음 React를 배웠다! html, css, js를 모두 합친거라니 신기하고 비동기하려고 힘들게 배운 것들이 리액트로는 쉽게 되는 것 같다. 오늘부터 React 사이트에 있는 Tictactoe game 구현하기 연습해보기 

목적 : 처음 배울 때 그리고 한 달 뒤에 얼마나 발전해있는지 확인하기 ! 

 

 


 

 

 

먼저 위 문서에서 가져온 html, css -> 그대로 복붙해서 기본 세팅하기

https://ko.reactjs.org/tutorial/tutorial.html#setup-for-the-tutorial

 

자습서: React 시작하기 – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

 

tictactoe.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TicTacToe</title>
    <link rel="stylesheet" href="tictactoe.css">

</head>

<body>
    <div id="errors" style=" background: #c00; color: #fff; display: none; 
                            margin: -20px -20px 20px; padding: 20px; white-space: pre-wrap;">
    </div>
    <div id="root"></div>

    <script>
        window.addEventListener('mousedown', function (e) {
            document.body.classList.add('mouse-navigation');
            document.body.classList.remove('kbd-navigation');
        });
        window.addEventListener('keydown', function (e) {
            if (e.keyCode === 9) {
                document.body.classList.add('kbd-navigation');
                document.body.classList.remove('mouse-navigation');
            }
        });
        window.addEventListener('click', function (e) {
            if (e.target.tagName === 'A' && e.target.getAttribute('href') === '#') {
                e.preventDefault();
            }
        });
        window.onerror = function (message, source, line, col, error) {
            var text = error ? error.stack || error : message + ' (at ' + source + ':' + line + ':' + col + ')';
            errors.textContent += text + '\n';
            errors.style.display = '';
        };
        console.error = (function (old) {
            return function error() {
                errors.textContent += Array.prototype.slice.call(arguments).join(' ') + '\n';
                errors.style.display = '';
                old.apply(this, arguments);
            }
        })(console.error);
    </script>
    
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script type="text/babel" src="./tictactoe.js"></script>
</body>
</html>

 

tictactoe.css

body {
    font: 14px "Century Gothic", Futura, sans-serif;
    margin: 20px;
  }
  
  ol, ul {
    padding-left: 30px;
  }
  
  .board-row:after {
    clear: both;
    content: "";
    display: table;
  }
  
  .status {
    margin-bottom: 10px;
  }
  
  .square {
    background: #fff;
    border: 1px solid #999;
    float: left;
    font-size: 24px;
    font-weight: bold;
    line-height: 34px;
    height: 34px;
    margin-right: -1px;
    margin-top: -1px;
    padding: 0;
    text-align: center;
    width: 34px;
  }
  
  .square:focus {
    outline: none;
  }
  
  .kbd-navigation .square:focus {
    background: #ddd;
  }
  
  .game {
    display: flex;
    flex-direction: row;
  }
  
  .game-info {
    margin-left: 20px;
  }
  

 

 

그리고 html 에 js를 연결해서 문서에 나온대로 연습해주기

    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script type="text/babel" src="./tictactoe.js"></script>

* 위의 코드들을 head 에 쓰게되면 js파일을 따로 빼서 쓸 때 작동하지 않는다. (처음 html을 쭉 - 로드할 때 읽히지않음) 

-> 위의 코드들을 body 아래쪽에 쓰면 된다. 

js파일을 따로 빼서 쓰지 않는다면 head에 넣어도 상관없다. 

 

 

 

 


 

 

 

Tictactoe Game 만들기 시작 👩‍💻

 

1. class Square Component 만들기 

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


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

 

class Square 는 square라는 class를 가진 button을 return 한다. 

근데 {this.props.value} 가 무슨 뜻이지,,,? 

요 안의 내용을 넣는 곳에 어떤 value를 넣을꺼다. 같은데 계속 공부하다 보면 나올 것 같다 ! 

 

 

 

 

 

 

 

className = 'square'  의 css 

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

 

2. class Board Component 만들어서 Sqaure와 연결

- render 를 두 번 한다. renderSquare는 Square 라는 class component에 return 한다 인가.... i 는 무엇이고...

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

class Board extends React.Component{
    renderSquare(i){
        return <Square value={i} />;
    }
    
    render(){
        const status = 'Next Player:X';

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

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

renderSquare(숫자) 는 함수  i는 인자값을 나타내는 것 같다. i는 Square의 value가 되어서 this.props.value로 return 하는 것 같다 (?) Board class return 에 9번 this.renderSquare()함수를 실행해서 각 숫자가 들어갔다.

 

 

css

  .board-row:after {    /* 테이블 정렬  */
    clear: both;
    content: "";
    display: table;
  }
  
    .status {    /* Next Player:X 와 table  사이에 margin 주기 위함  */
    margin-bottom: 10px;
  }
  

.board-row:after 로 table로 나타냈다. 저게 삭제되면

이렇게 나온다.

 

 

 

 

3. gameboard class component 만들어서 위의 내용들 붙여주기 

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

class Board extends React.Component{
    renderSquare(i){
        return <Square value={i} />;
    }
    
    render(){
        const status = 'Next Player:X';

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

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

딱히 달라지는 건 없고 div 에 <Board /> class를 가져왔다! 

내일은 위의 내용들 이해 더 하고 코드를 외워보기 ! 

 

 

-1일차 끗-

반응형