본문 바로가기
Framework/react

[리액트] 클래스형 컴포넌트 함수형 컴포넌트로 변환하기. Assignment to constant variable.

by 딸기뚜왈기 2024. 6. 20.

 

https://belle-sooir.tistory.com/126

 

[리액트]클래스형 컴포넌트를 함수형 컴포넌트로 변환하기.

함수형 컴포넌트로 변환할 때 constructor, super, this.state는 더 이상 사용할 수 없고대신, 함수형 컴포넌트는 useState와 같은 훅(hooks)을 사용하여 상태를 관리한다.클래스형 컴포넌트 -> 함수형 컴포넌

belle-sooir.tistory.com

 

 

Game.js

 

<클래스형 컴포넌트 >

import React from 'react';
import Board2 from './Board2';
import calculateWinner from './calculateWinner';
import '../App.css';

class Game2 extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      history: [
        {
          squares: Array(9).fill(null)
        }
      ],
      stepNumber: 0,
      xIsNext: true,
      boardSize: 6,
      APlayer: 0,
      BPlayer: 0,
      // count: 8
    };
  }
  // function Lifes() {
  //   const lifecount = 8
  //   for (let i=0; i<=lifecount; i++ ) {
  //     if (i===lifecount) {
  //       return i;
  //     }
  // }}

  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 (this.state.xIsNext) {
        this.state.APlayer +=1;
      } else {
        this.state.BPlayer +=1;}

      if (calculateWinner(squares, this.state.boardSize) || squares[i]) {
        return;
      }
      squares[i] = this.state.xIsNext ? "X" : "O";
      console.log(this.state.xIsNext)
      this.setState({
        history: history.concat([
          {
            squares: squares
          }
        ]),
        stepNumber: history.length,
        xIsNext: !this.state.xIsNext,
        APlayer : this.state.APlayer,
        BPlayer : this.state.BPlayer
        // count: this.state.count >= 8 ? this.state.count -= 1 : this.state.count = 0
      });
    }

  jumpTo(step){
    this.setState({
      stepNumber: step,
      xIsNext: (step % 2) === 0
    });
  }

  render() {
    const history = this.state.history;
    const current = history[this.state.stepNumber];
    const winner = calculateWinner(current.squares, this.state.boardSize);
    const count = 9-history.length
    const APlayer = this.state.APlayer
    const BPlayer = this.state.BPlayer
    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>
      );
    });


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

    return (
      <div className="game">
        <div className="game-board">
          <Board2
          squares={current.squares}
          onClick={i => this.handleClick(i)}
          size={this.state.boardSize}
          counts={count}
          APlayer={APlayer}
          BPlayer={BPlayer}
          // APlayerScore={this.state.APlayer}
          // BPlayerScore={this.state.BPlayer}
          />
        </div>
        <div className="game-info">
          <div>{status}</div>
          <ol>{moves}</ol>
        </div>
        <div className='game-score'>
          <table>
            <thead>
            <tr><td>X</td><td>O</td></tr>
            </thead>
            <tbody>
            <tr><td>{this.state.APlayer}</td><td>{this.state.BPlayer}</td></tr>
            </tbody>
          </table>
        </div>
        <div>
          <h1>{count}</h1>
        </div>
      </div>
    );
  }
}

  export default Game2;

 

 

 

함수형 컴포넌트로 전환 시도 중 오류발생

Assignment to constant variable>

 

<에러원인>

이미 할당한 const 변수에 새로운 값을 할당했을 때 발생한다.

const 변수는 재할당을 허용하지 않기 때문.

 

재할당이 불가능한 const의 쓰임:
값을 수정하면 안되는 변수를 만들때 유용합니다.
상수를 선언할 때 쓰임

 

 

<해결방법>

값을 재할당해서 사용할 수 있는 let을 사용한다.

 

이 부분에서 에러가 나는 것 같다. 굳이 useState를 쓸 필요가 없을 것 같다.

 

 

<수정전>

 

 

 

 

<수정 후 >  함수형 컴포넌트로 전환 완료.

import React, {useState} from 'react';
import Board3 from './Board3';
import calculateWinner from './calculateWinner';
import '../App.css';

function Game3 (props) {
    const [history, setHistory] = useState([{
        squares : Array(9).fill(null)}]);
    const [stepNumber, setStepnumber] = useState(0);
    const [xIsNext, setXIsnext] = useState(true);
    const [boardSize, setBoardsize] = useState(6);
    let aPlayer = 0;
    let bPlayer = 0;
   
    const handleClick = (i) => {
      const historycopy = history.slice(0, stepNumber + 1);
      const current = historycopy[historycopy.length - 1];
      const squares = current.squares.slice();
        if (xIsNext) {
            aPlayer += 1;
        } else {
            bPlayer += 1;
        }


        if (calculateWinner(squares, boardSize) || squares[i]) {
            return;
        }
        squares[i] = xIsNext ? "X" : "O";
        setHistory(historycopy.concat([{squares: squares}]));
        setXIsnext(!xIsNext);
        setStepnumber(history.length);
    }

    const jumpTo = (step) => {
        setStepnumber(step);
        setXIsnext((step % 2) === 0);
  }

    const current = history[stepNumber];
    const winner = calculateWinner(current.squares, boardSize);
    const count = 9-history.length
    const moves = history.map((step, move) => {
      const desc = move ?
        'Go to move #' + move :
        'Go to game start';

      return (
        <li key={move}>
          <button onClick={() => jumpTo(move)}>{desc}</button>
        </li>
      );
    });


    let status;
    if (winner) {
      status = 'Winner' + winner;
    } else {
      status = 'Next player: ' + (xIsNext ? 'X' : 'O');
    }

    return (
      <div className="game">
        <div className="game-board">
          <Board3
          squares={current.squares}
          onClick={i => handleClick(i)}
          size={boardSize}
          counts={count}
          />
        </div>
        <div className="game-info">
          <div>{status}</div>
          <ol>{moves}</ol>
        </div>
        <div className='game-score'>
          <table>
            <thead>
            <tr><td>X</td><td>O</td></tr>
            </thead>
            <tbody>
            <tr><td>{aPlayer}</td><td>{bPlayer}</td></tr>
            </tbody>
          </table>
        </div>
        <div>
          <h1>{count}</h1>
        </div>
      </div>
    );
  }

  export default Game3;

 

 

<var, let, const 차이>



  재할당 예시 재선언 예시
const x const x = 10; // 변수 선언 및 초기화
console.log(x); // 출력: 10

x = 20; // 변수 재할당 시도 -> 에러 발생
// Uncaught TypeError: Assignment to constant variable.
x const y = 5; // 변수 선언 및 초기화
console.log(y); // 출력: 5

const y = 15; // 변수 재선언 시도 -> 에러 발생
// Uncaught SyntaxError: Identifier 'y' has already been declared
let o let x = 10; // 변수 선언 및 초기화
console.log(x); // 출력: 10

x = 20; // 변수 재할당 console.log(x); // 출력: 20
x let y = 5; // 변수 선언 및 초기화
console.log(y); // 출력: 5

let y = 15; // 변수 재선언 시도 -> 에러 발생
// Uncaught SyntaxError: Identifier 'y' has already been declared
var o var x = 10; // 변수 선언 및 초기화
console.log(x); // 출력: 10

x = 20; // 변수 재할당 console.log(x); // 출력: 20
o var y = 5; // 변수 선언 및 초기화
console.log(y); // 출력: 5

var y = 15; // 변수 재선언 및 재초기화
console.log(y); // 출력: 15