일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- nodejs교과서
- 리액트
- 제로초예제
- sementicversion
- 리액트컴포넌트
- nodeJS
- npm명령어
- node
- 리액트스타디
- React
- React Component
- mongo
- 클래스컴포넌트
- sequelize
- NPM
- mongoose
- component
- 리액트기초
- 시퀄라이즈
- MongoDB
- NoSQL
- express-generator
- 시퀄라이즈공부
- Today
- Total
개발노트
11 (2)hooks / useEffect 본문
우선 훅스에는 라이프사이클없으니까 제외한 나머지를 훅스로 변경
import React, { useState , useRef } from 'react';
const rpsCoords = {
rock:'0px',
scissor: '-142px',
paper: '-284px',
};
const score = {
scissor: 1, //가위
rock:0, //바위
paper:-1 //보
}
//컴퓨터가 어떤손 내는지 판단
const computerChoice = (imgLocation)=>{
return Object.entries(rpsCoords).find( function(v){
return v[1] === imgLocation;
})[0];
}
const RPS =()=> {
const [ result, setResult ] = useState('');
const [ imgLocation, setImgLocation] = useState(0);
const [ score, setScore ] = useState(0);
const interval = useRef();
const interval;
// componentDidMount(){ //첫렌더링 된후
// //이미지 위치값을 묵 으로
// //인터발을 걸어주는데 안에 화살표함수에서 img위치가 rsp위치의 묵과 같다면
// // 상태값의 이미지위치를 가위로
// this.setState( {imgLocation: rpsCoords.rock });
// this.changeHand();
// }
// componentWillUnmount(){ // 제거직전
// }
// componentDidUpdate(){ //리렌더링된후 실행
// }
const changeHand = ()=>{
interval.current = setInterval( ()=>{
if( imgLocation == rpsCoords.rock ){
setImgLocation(rpsCoords.scissor);
}else if( imgLocation == rpsCoords.scissor ){
setImgLocation(rpsCoords.scissor);
}else{
setImgLocation(rpsCoords.rock);
}
}, 500 );
}
//사용자가 가위바위보 선택했을때
const onClickBtn = ( userChoose )=>{
clearInterval( this.interval );
const userScore = score[userChoose]; //siccer 1
const comScore = score[computerChoice(imgLocation)]; //paper -1
const diff = userScore - comScore; //결과
if(diff === 0){ //
setResult('again')
}else if( [-1, 2].includes(diff) ){ //이겼음
setResult( 'win!');
setScore( ( prevScore )=>{ return[...prevScore, +1 ] } );
}else{ //졌다
setResult('lose');
setScore( ( prevScore )=>{ return[...prevScore, -1 ] } );
}
clearInterval(this.interval);
setTimeout( ( )=>{ this.changeHand() }, 2000 );
}
return(
<>
<div id="computer" style={{ background: `url(https://en.pimg.jp/023/182/267/1/23182267.jpg) ${imgLocation} 0` }} />
<ul>
<li id="scissor" className="btn" onClick={ ()=>{ onClickBtn('scissor')} }> 가위</li>
<li id="rock" className="btn" onClick={ ()=>{ onClickBtn('rock')} }> 바위</li>
<li id="paper" className="btn" onClick={ ()=>{ onClickBtn('paper')} }> 보</li>
</ul>
<p>{result}</p>
<p>현재 {score}점</p>
</>
)
}
export default RPS;
class component는 컴포넌트 생성업데이트소멸 에 따라 이벤트가 있는것처럼
Hook에서의 useEffect
-컴포넌트가 처음 화면에 나타나게 될때, 화면에서사라지게 될때 이벤트를 걸 수 있다
-props나 state가 update 되기 전, 될때 도 이벤트를 걸 수 있다
-리렌더링 될때마다 이벤트를 걸 수도 있다.
useEffect( ()=>{ '하고자하는작업' } , [ dependency.. 배열 ] )
테스트해본결과
배열(의존값)이 없을경우엔,
처음 렌더링될때 컴포넌트가 그려지는 갯수만큼 실행이 됨.
그리고 return안은 만약 componentDidMount 때 인스턴스생성을 해줬다면
componentWillUnmount 때 처럼 인스턴스 제거를 해주는 역할.
컴포넌트 remove했을때 발생.
useEffect ( ()=>{ //componentDidMount
//첫렌더링된후, 컴포넌트가그려질때 발생
console.log('컴포넌트 갯수만큼 그려질때마다, 실행');
//인스턴스생성
return()=>{ //componentWillUnmount
//컴포넌트가 화면에서 사라질때. 발생
console.log('unmount');
//인스턴스제거
}
},[])
배열에 등록할 경우
useEffect ( ()=>{ //componentDidMount , componentDidUpdate
//첫렌더링된후, 컴포넌트가그려질때 발생
console.log('A : 컴포넌트 처음 그려질때, 업데이트 되서 그려질때');
return()=>{ // componentDidUpdate
//컴포넌트의 props, state가 업데이트 될때 발생
console.log(' B : before update .. state ');
}
},[ props, state ])
배열 값이(상태가) 바뀔때마다 호출이 됨.
배열안의 의존값이(state또는 props)가 들어가면 componentDidUpdate역할에 좀더 가까워 지는것 같다.
return() 이 실행되서 update전에 호출이 된다음
상태가 바뀌고 A가 실행됨.
state바뀔때 hook함수 전체가 재 실행되기 때문에
업데이트하고 그려주고 해서 B , A 가 발생
배열[] 의존성등록을 해주지 않을 경우
useEffect ( ()=>{ //componentDidMount, componentDidUpdate 역할
//첫렌더링된후
console.log( ' 1 :Start');
changeHand();
return()=>{ //componentWillUnmount
console.log('2 :End');
clearInterval( interval.current ); //////
}
},[ ])
const changeHand = ()=>{
interval.current = setInterval( ()=>{
console.log("imgLocation:"+imgLocation);
if( imgLocation == rpsCoords.rock ){
console.log('rock');
setImgLocation(rpsCoords.scissor);
}else if( imgLocation == rpsCoords.scissor ){
console.log('scissor');
setImgLocation(rpsCoords.paper);
}else{
console.log('paper');
setImgLocation(rpsCoords.rock);
}
}, 2000 );
}
실행할때 render일어나서 화면변한다음,
그다음부턴 렌더링일어나지 않고,
내부적으로만 setInterval이 실행되는데,
상태값을 변경해주지 않음...
useEffect ( ()=>{ //componentDidMount, componentDidUpdate 역할
//첫렌더링된후
console.log( ' 1 :Start');
changeHand();
return()=>{ //componentWillUnmount
console.log('2 :End');
clearInterval( interval.current ); //////
}
},[ imgLocation ])
const changeHand = ()=>{
interval.current = setInterval( ()=>{
console.log("imgLocation:"+imgLocation);
if( imgLocation == rpsCoords.rock ){
console.log('rock');
setImgLocation(rpsCoords.scissor);
}else if( imgLocation == rpsCoords.scissor ){
console.log('scissor');
setImgLocation(rpsCoords.paper);
}else{
console.log('paper');
setImgLocation(rpsCoords.rock);
}
}, 2000 );
}
의존성값이 없을경우, setImgLocation 부분이 실행이 되지 않아서
state 즉 바꿔주는부분 []의존성배열에 추가해야 정상적으로 작동.
추가후
변경하고싶은 상태값의 경우 의존성배열에 꼭 넣어줘야 상태값이 바뀐다는점.
화면 렌더링도 의존성배열에 있어야 바뀌줌
useEffect를 여러개 쓸 수도 있다.
useEffect ( ()=>{
},[ imgLocation ]);
useEffect ( ()=>{
},[ rpsCoords ])
useEffect ( ()=>{
},[ ])
-hooks는 부모컴포넌트 변경시 자식컴포넌트도 무조건 변경됨
그래서 리렌더링 안되게 하려면 memo로 감싸준다.
-hooks는 useState같은 리액트패키지를 써야 훅스고
안쓰면 그건 그냥 함수형 컴포넌트
<html lang="ko">
<head>
<meta charset="utf-8">
<title>game</title>
</head>
<style>
#computer {
width: 142px;
height: 200px;
background-position: 0 0;
outline: 5px solid gold;
}
ul{width:100%; padding:0; height:180px;}
li{ width: 142px; height:180px; outline:1px solid grey; float:left; list-style:none; }
li{
background: url(https://en.pimg.jp/023/182/267/1/23182267.jpg) 0px -11px;
}
li#scissor{
background-position: -142px -11px;
}
li#paper{
background-position: -284px -11px;
}
</style>
<body>
<div id="root"></div>
<script src="./dist/app.js">
</script>
</body>
</html>
'React > basic' 카테고리의 다른 글
12. hooks / useEffect , useMemo (0) | 2020.07.28 |
---|---|
12. componentDidUpdate , setInterval (0) | 2020.07.27 |
11. react life cycle (0) | 2020.07.26 |
10. (4)jsx 에서 for, if (0) | 2020.07.26 |
10. (3) hooks / useState (0) | 2020.07.26 |