본문 바로가기
my_lesson/_ReactJS

ReactJS - interactive game -create-react-app

by boolean 2018. 4. 17.
728x90


ReactJS - interactive game -create-react-app 

 

  • react v16.3.2
  • create-react-app v1.5.2
  • /...../ 는 생략되었다는 표시임
  • 파란 글씨는 추가된 것임
  • 빨간 글씨는 수정된 것임

  • NodeJS, NPM, Yarn 설치 [바로가기]

    django+reactjs project [바로가기]

    상호작용하는 게임을 만들면서 ReactJS를 익혀보자 원문보기

    ~$ yarn create react-app my-app  //2020.01.15 Update
    ~$ cd my-app
    ~my-app$ rm -f src/*   && touch index.js  && touch index.css // don't delete the folder, just its contents

    ~my-app/src$ index.js
    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';

    class Square extends React.Component {
    render() {
    return (
    <button className="square">
    {/* TODO */}
    </button>
    );
    }
    }

    class Board extends React.Component {
    renderSquare(i) {
    return <Square />;
    }

    render() {
    const status = 'Next plager: 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(2)}
    </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')
    );

    ~my-app/src$ index.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;
    }

    ~my-app/src$ index.js

    /....../

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

    }

    /....../

    onClick={alert('click')}을 하면 즉시 alert가 실행된다.

    state

    ~my-app/src$ index.js

    /....../

    class Square extends React.Component {

    constructor(props) {

    super(props);

    this.state = {

    value: null,

    };

    }

    render() {

    return (

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

    {this.state.value}

    </button>

    );

    }

    }

    /....../




    /....../

    // Function Components
    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),
    };
    }

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

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

    /....../
    class Game extends React.Component {
    render() {
    return (
    <div className="game">
    /....../
    <div className="game-board">
    </div>
    </div>
    );
    }
    }
    /....../


    Declaring a Winner


    /....../
    function Square(props) {
    /....../
    }
    class Board extends React.Component {
    constructor(props) {
    /....../
    }

    handleClick(i) {
    /....../
    }

    renderSquare(i) {
    /....../
    }

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

    return (
    /....../
    );
    }
    }




    class Game extends React.Component {
    /....../
    }

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

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



    ignore the click if someone has already won the game or if a square is already filled
    /....../

    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,

    });

    }

    /....../


    Storing History

    Let's plan to store an object lik\e this in state:

    import React from 'react';

    import ReactDOM from 'react-dom';

    import './index.css';



    function Square(props) {

    return (

    <button className="square" onClick={props.onClick}>

    {props.value}

    </button>

    );

    }



    class Board extends React.Component {


    renderSquare(i) {

    return (

    <Square

    value={this.props.squares[i]}

    onClick={() => this.props.onClick(i)}

    />

    );

    }


    render() {

    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 {

    constructor(props) {

    super (props);

    this.state = {

    history: [{

    squares: Array(9).fill(null),

    }],

    xInsNext: true,

    }

    }


    handleClick(i) {

    const history = this.state.history;

    const current = history[history.length -1];

    const squares = current.squares.slice();

    if (calculateWinner (squares) || squares[i]) {

    return;

    }

    squares[i] = this.state.xIsNext ?  'X' : 'O';

    this.setState({

    history: history.concat([{

    squares: squares

    }]),

    xIsNext: !this.state.xIsNext,

    });

    }


    render() {

    const history = this.state.history;

    const current = history[history.length - 1];

    const winner = calculateWinner(current.squares);


    let status;

    if (winner) {

    status = 'Winner: ' + winner;

    } else {

    status = 'Next player: ' + (this.state.xInsNext ? 'X' : 'O');

    }


    return (

    <div className = "game">

    <div className = "game-board">

    <Board

    squares={current.squares}

    onClick={(i) => this.handleClick(i)}

    />

    </div>

    <div className = "game-info">

    <div> {status} </div>

    <ol> {/* TODO */}</ol>

    </div>

    </div>

    );

    }

    }


    ReactDOM.render(

    <Game />,

    document.getElementById('root')

    );


    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;

    }

    Showing the moves



    https://reactjs.org/tutorial/tutorial.html#getting-started

    댓글