TIL 22-04-10 (2)

thisisyjin·2022년 4월 10일
0

TIL 📝

목록 보기
19/113

React.js

Today I Learned ... react.js

🙋‍♂️ React.js Lecture

🙋‍ My Dev Blog


React Lecture CH 5

1 - 라이프사이클
2 - setInterval과 라이프사이클 연동
3 - 가위바위보 게임
4 - 고차함수 (Higher-order Func)
5 - useEffect
6 - 클래스 vs Hooks 라이프사이클 비교

라이프사이클

  • 가위바위보 게임 제작
    -> setInterval과 clearInterval 이용

초기 코드 작성

import React, { Component } from React;

class RSP extends Component {

    state = {
        result: '',
        score: 0,
        imgCoord: 0
    };

    render() {
        const { result, score, imgCoord } = this.state;
        return (
            <>
      <div id="computer" style={{ background: `url(https://en.pimg.jp/023/182/267/1/23182267.jpg) ${imgCoord} 0` }} />
      <div>
        <button id="rock" className="btn" onClick={onClickBtn('바위')}>바위</button>
        <button id="scissor" className="btn" onClick={onClickBtn('가위')}>가위</button>
        <button id="paper" className="btn" onClick={onClickBtn('보')}></button>
                </div>
                <div>{result}</div>
                <div>현재 {score}</div>
    </>
            
        );
    }
}

위 div#computer의 background 이미지를 줘서
가위/바위/보 이미지가 차례로 나오도록 한다.

  • 단, background image의 src는 스프라이트 이미지이다.
  • 따라서, 해당 JSX 요소에 style 어트리뷰트의 background-position을 조정하여 잘라내서 사용.
    -> 축약형인 background 에서 두번째 항목.

📌 이미지 스프라이트 (image sprite)

  • 여러개의 이미지가 포함된 하나의 이미지.
  • 사용할때는 일부만 추출.
    (background-position 속성으로)

componentDidMount()

가위바위보 게임이 처음 렌더링 되자마자 실행되도록 하려고 한다.
🔻
lifeCycle method인 componentDidMount()를 사용하자.
-> 첫 렌더링시에만 실행된다. (리렌더링시 실행되지 ❌)

참고 - 지난번에 배운 lifeCycle Method

shouldComponentUpdate
-> 리렌더링 여부 결정 (true/false)

componentDidUpdate()

  • 리렌더링시. (setState나 props 변경 등 변경사항이 있을때)

componentWillUnmount()

  • 보통은 componentDidMount와 componentWillUnmount가 쌍으로 쓰인다.
    (= componentDidMount에서 설정한 것을 해제해줌)
componentDidMountcomponentWillUnmount
컴포넌트가 첫 렌더링 된 후.
주로 비동기 요청을 함.
컴포넌트가 제거되기 직전.
(부모컴포넌트가 자신을 없앴을 때)
비동기 요청 정리.

예>
컴포넌트가 제거되었지만, setInterval() 즉 비동기요청은 제거되지 않음.
-> componentWillUnmount()에서 제거해야함.

componentDidMount() {
  setInterval(() => {
  console.log('hello');
  }, 1000);
}

componentWillUnmount() {
  // 여기서 clearInterval() 해줘야함.
}

EX>

class RSP extends Component {
    state = {
        result: '',
        score: 0,
        imgCoord: 0
    };

    interval;

    componentDidMount() {
        this.interval = setInterval(() => {
            console.log('hello')
        }, 1000);
    }

    componentWillUnmount() {
        clearInterval(this.interval); // 비동기 동작 정리함
    }

코드 작성 - setInterval

RSP.jsx

import React, { Component } from 'react';

const rspCoords = {
  가위: '0',
  바위: '-142px',: '-284px',
};

const scores = {
  이김: 1,
  비김: 0,: -1,
};

class RSP extends Component {
  state = {
    result: '',
    score: 0,
    imgCoord: '0',
  };

  interval;

  componentDidMount() {
    this.interval = setInterval(() => {
      const { imgCoord } = this.state;
      if (imgCoord === rspCoords.바위) {
        this.setState({
          imgCoord: rspCoords.가위,
        });
      } else if (imgCoord === rspCoords.가위) {
        this.setState({
          imgCoord: rspCoords.,
        });
      } else if (imgCoord === rspCoords.) {
        this.setState({
          imgCoord: rspCoords.바위,
        });
      }
    }, 1000);
  }

  onClickBtn = (choice) => {};

  render() {
    const { result, score, imgCoord } = this.state;
    return (
      <>
        <div
          id="computer"
          style={{
            background: `url(https://en.pimg.jp/023/182/267/1/23182267.jpg) ${imgCoord} 0`,
          }}
        />
        <div>
          <button id="rock" className="btn" onClick={this.onClickBtn('바위')}>
            바위
          </button>
          <button
            id="scissor"
            className="btn"
            onClick={this.onClickBtn('가위')}
          >
            가위
          </button>
          <button id="paper" className="btn" onClick={this.onClickBtn('보')}></button>
        </div>
        <div>{result}</div>
        <div>현재 {score}</div>
      </>
    );
  }
}

export default RSP;

주의

  • 비동기 함수 바깥의 변수를 참조시 클로저가 발생한다!
    (클로저란, 외부 함수보다 중첩 함수의 생존 시간이 긴 경우)
componentDidMount() {
    this.interval = setInterval(() => {
      const { imgCoord } = this.state;  // 👈 이부분을 setInterval()의 콜백 안에 넣어줘야함!!!
      if (imgCoord === rspCoords.바위) {
        this.setState({
          imgCoord: rspCoords.가위,
        });

  • 1초마다 이미지가 변경된다.
  • componentWillUnmount에서 clearInterval 해주기.
  componentWillUnmount() {
    clearInterval(this.interval);
  }
profile
기억은 한계가 있지만, 기록은 한계가 없다.

0개의 댓글