[React] 튜토리얼 ⑤를 시도했습니다.

62458 단어 Reacttech

컨디션


Windows10Pro

카탈로그


① React 프로젝트를 제작하고 웹을 통해 액세스할 수 있는지 확인합니다.
https://zenn.dev/taka_tech/articles/773da5de8c822a
②클릭한 공백×탭
https://zenn.dev/taka_tech/articles/17600f9bc5d4b5
③ 클릭 시 번호 추가×교체 디스플레이
https://zenn.dev/taka_tech/articles/e1c0b0b01e9b96
④ 승리 판정을 실시한다.
https://zenn.dev/taka_tech/articles/d52991cdb0cbfd
⑤ 설치 내역 기능.← 여기

최종 목표


React 튜토리얼을 만드는 세 가지 배열 게임
https://ja.reactjs.org/tutorial/tutorial.html

목표 ⑤


역사적 기능을 실현하다.

실천하다


역사 정보를 저장할 수 있는 그룹을 준비합니다


Board 구성 요소의 squares 배열입니다. 순서대로 저장해야 합니다.이번에는 히스토리라는 배열을 준비해 squares 배열을 넣었다.
index.js
// イメージ
history = [
  // Before first move
  {
    squares: [
      null, null, null,
      null, null, null,
      null, null, null,
    ]
  },
  // After first move
  {
    squares: [
      null, null, null,
      null, 'X', null,
      null, null, null,
    ]
  },
  // After second move
  {
    squares: [
      null, null, null,
      null, 'X', null,
      null, null, 'O',
    ]
  },
  // ...
]

state의 향상


역사 정보를 참고하는 것은 최고급 게임 구성 요소입니다.이를 위해서는 홈 구성 요소가 History 배열에 접근할 수 있어야 합니다.History 패턴의 state를 사용하여 Game 어셈블리를 사용할 수 있습니다.Square 구성 요소의 state가 Board 구성 요소로 향상되면 Board 구성 요소의 state도 Game 구성 요소로 향상됩니다.
index.js
// Boardコンポーネント
class Board extends React.Component {
    // コンストラクタ
-    constructor(props) {
-        super(props);
-        this.state = {
-            squares: Array(9).fill(null),
-            xIsNext: true,
-        };
-    }
    
// Gameコンポーネント
class Game extends React.Component {
    // コンストラクタ
+    constructor(props) {
+        super(props);
+        this.state = {
       // 上のイメージ配列
+            history: [{
+                squares: Array(9).fill(null),
+            }],
+            xIsNext: true,
+        };
+    }
squares 어레이와 onClick 이벤트가 Game 구성 요소에서 수신되기 때문에
renderSquare 방법은 다음과 같은 수정이 필요합니다.
index.js
    renderSquare(i) {
        return (
            <Square
+                value={this.props.squares[i]}
+                onClick={() => this.props.onClick(i)}
            />
        )
    }
게임 구성 요소의render 방법을 통해 최신 역사 기록에서 게임 정보를 결정합니다.
index.js
  // Gameコンポーネント
    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.xIsNext ? '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>
        );
    }
}
그런 다음 Board 구성 요소의 render 방법을 사용하여 해당 코드를 삭제합니다.
index.js
    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>
        );
    }
마지막으로handleClick 메서드를 Board 어셈블리에서 Game 어셈블리로 이동합니다.history를 사용하기 때문에 전선의 차이에 주의해야 한다.
index.js
    // Boardコンポーネント
    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,
        });
    }
    
    // Gameコンポーネント
    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,
        });
    }

과거 기록 보이기


맵 방법을 사용하면 역사 기록의 수량 단추만 표시합니다.
index.js
 render() {
        const history = this.state.history;
        const current = history[history.length - 1];
        const winner = calculateWinner(current.squares);

+        const moves = history.map((step, move) => {
+            const desc = move ?
+                'Go to move #' + move :
+                'Go to game start';
+            return (
+                <li>
+                    <button onClick={() => this.jumpTo(move)}>{desc}</button>
+                </li>
+            );
+        });

        let status;
	        if (winner) {
            status = 'Winner: ' + winner;
        } else {
            status = 'Next player: ' + (this.state.xIsNext ? '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>{moves}</ol>
                </div>
            </div>
        );
이때 게임을 하면 한 번 할 때마다 버튼이 늘어나는 것을 확인할 수 있다.

버튼을 누르면,this.jump To 메서드가 구현되지 않은 오류가 발생했습니다.
개발자 도구의 컨트롤러에서 다음 경고를 볼 수 있습니다.

키 선택


동적 목록을 만들려면 키라고 하는 React의 특수 속성을 지정해야 합니다.render 방법의 리 탭으로 키를 설정합니다.
index.js
        const moves = history.map((step, move) => {
            const desc = move ?
                'Go to move #' + move :
                'Go to game start';
            return (
+                <li key={move}>
                    <button onClick={() => this.jumpTo(move)}>{desc}</button>
                </li>
            );
        });

되감기 기능의 설치


게임 구성 요소의 state에 저장이 현재 몇 번째 변수입니다.
index.js
constructor(props) {
        super(props);
        this.state = {
            history: [{
                squares: Array(9).fill(null),
            }],
+            stepNumber: 0,
            xIsNext: true,
        };
    }
게임 구성 요소에서 번호를 업데이트하고 진위를 업데이트하는 JunpTo 방법입니다.
index.js
    jumpTo(step) {
        this.setState({
            stepNumber: step,
            xIsNext: (step % 2) === 0,
        });
    }
새로운 프로그램이 발생할 때, 프로그램 수의 state를 업데이트해야 합니다.handleClick 메서드의 setState를 사용하여 step Number를 업데이트합니다.
index.js
    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,
            }]),
+            stepNumber: history.length,
            xIsNext: !this.state.xIsNext,
        });
    }

잃어버린 미래 삭제


리코더 기능을 사용하여 리코더를 한 번 조작한 경우 리코더 전의 미래 디스크 정보를 삭제해야 한다.따라서 현재 표시된 번호까지의 역사 기록만 보존한다.즉, step Number를 축으로 삼아 히스토리 정보를 처리합니다.
index.js
    handleClick(i) {
+        const history = this.state.history.slice(0, this.state.stepNumber + 1);
        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,
            }]),
            stepNumber: history.length,
            xIsNext: !this.state.xIsNext,
        });
    }
    render() {
        const history = this.state.history;
+        const current = history[this.state.stepNumber];
        const winner = calculateWinner(current.squares);

        const moves = history.map((step, move) => {

완성



감상


React의 독특한 state 아이디어와 렌더의 아이디어를 체험했다.
승강기 등은 습관이 필요하기 때문에 이후에도 뭔가를 하고 싶어한다.

좋은 웹페이지 즐겨찾기