ComponentDidMount
- render()가 최초 실행 후 실행되는 메서드. (state변경으로 인한 리렌더링이 일어나도 해당 메서드는 재실행되지 않는다.)
- 해당 메서드에 비동기 요청을 많이 한다.
[비동기 함수 중 setInterval 주의 점]
- setInterval을 하고 취소를 하지 않으면 해당 컴포넌트가 사라져도 무한히 실행된다.
- setInterval을 하고 취소를 하지 않고, 해당 컴포넌트를 제거, 생성을 반복하면 취소되지 않은 setInterval은 중첩되어 문제가 생긴다.
복습 : 라이프사이클
클래스 컴포넌트 라이프사이클
- 생성자(constructor) → render → ref설정 → componentDidMount
- setState / props 바뀔 때 → shouldComponentUpdate (리렌더할지말지 결정하는 함수) → render → componentDidUpdate
- 부모가 나를 없앴을 때 → componetWillUnmount → 소멸
라이프사이클 관련 메서드
componentDidMount : 렌더가 처음실행되고 componentDidMount가 실행된다. (state변경으로 인한 리렌더링이 일어나도 실행되지 않는다.)
componentDidUpdate : 리렌더링 후에는 해당 메소드가 실행된다.
componentWillUnmount : 컴포넌트가 제거되기 직전
RSP 강의 안보고 짠 전체코드
import React, {Component} from "react";
//클래스의 경우 -> constructor -> render -> ref설정 -> componentDidMount ->
// setState, props 바뀔 때 -> shouldComponentUpdate -> render -> componentDidUpdate
// 부모가 나를 없앴을 때 componentWillUnmount -> 소멸
class RSP extends Component{
state = {
result:'',
score:0,
imgCoord:0,
}
intervalId = null;
position = 0;
clickable = true;
// 렌더가 처음실행되고 componentDidMount가 실행된다. (state변경으로 인한 리렌더링이 일어나도 실행되지 않는다.)
componentDidMount() {
//여기에 비동기 요청을 많이 한다.
//만약에 setInterval을 여기다가 쓰고 취소하는 코드를 쓰지않으면 RSP 컴포넌트가 사라지더라도 계속 setInterval은 실행된다.
//만약에 RSP 컴포넌트가 붙었다가 떼어지면 setInterval이 1번 중첩되어있지만 RSP컴포넌트가 한번 더 붙으면 setInterval이 2번 중첩되어 실행된다.
this.startRsp();
}
//리렌더링 후에는 해당 메소드가 실행된다.
componentDidUpdate(prevProps, prevState, snapshot) {
}
//컴포넌트가 제거되기 직전
componentWillUnmount() {
//componentDidMount, componentDidUpdate에서 비동기 작업을 했는데 그게 남아있으면 문제가 되기 떄문에 그런 애들을 정리해주는 것이 componentWillUnmount 이다.
clearInterval(this.intervalId);
}
onClick = (e) => {
if(!this.clickable)return; //연속클릭 방지
this.clickable = false;
const {target} = e;
const id = target.id;
clearInterval(this.intervalId);
let userValue = 0;
if(id === 'scissor'){
userValue = 1;
}else if(id === 'paper'){
userValue = 2;
}
if(userValue === this.position){
console.log('무승부!');
this.setState({result:'비겼습니다.'});
} else if((userValue+1) % 3 === this.position){
console.log('이겼어');
this.setState((prev) => ({...prev, score:prev.score+1, result:'이겼습니다.'}));
} else{
console.log('졌어')
this.setState((prev) => ({...prev, score:prev.score-1, result:'졌습니다.'}));
}
setTimeout(()=>{this.startRsp(); },1000)
setTimeout(()=>this.clickable = true, 1500)
}
startRsp(){
const positionArr = [0, 142, 284];
let currentIndex = 0;
if(this.intervalId)clearInterval(this.intervalId);
this.intervalId = setInterval(()=>{
this.position = currentIndex % positionArr.length;
const pix = positionArr[this.position];
this.setState({imgCoord:`-${pix}px`});
//console.log(positionArr[index], this.state);
currentIndex++;
},100);
}
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.onClick}>바위</button>
<button id="scissor" className="btn" onClick={this.onClick}>가위</button>
<button id="paper" className="btn" onClick={this.onClick}>보</button>
<div>{score}</div>
<div>{result}</div>
</>
)
}
}
export default RSP
'코딩이야기 > 인터넷 강의' 카테고리의 다른 글
section4. 5-6 클래스와 Hooks 라이프사이클 비교 (1) | 2024.05.31 |
---|---|
section4. 5-5 Hooks와 useEffect (0) | 2024.05.30 |
section4. 5-1 리액트 라이프사이클 소개 (0) | 2024.05.28 |
section4. 4-3 성능 체크와 Q&A, 4-4. 반응속도체크 Hooks 전환 (0) | 2024.05.28 |
section4. 4-2. setTimeout넣어 반응속도체크 (0) | 2024.05.27 |