useEffect에 대해 설명하기 전
이때까지 사용한객체지향(OOP) 함수형 프로그래밍에대해 알아보자
함수형 프로그래밍
→ 토끼가 하는 일이 각각의 함수
우리는 이미 React에서 rafce를 통해 함수형 프로그래밍을 하고있었음
그럼 React는 함수형 프로그래밍만 가능할까?
Class Component방식으로 진행했었음
-state,props,component, +)ref, context → 클래스에서만 사용이 가능했다
React Hook
-기존에 사용하던 방식과 달리 함수형 프로그래밍으로 리액트롤 활용할 때, 쉽게 문법을 쓸 수 있도록 나온 기능
ex) use~
→ rafce로 가능
리액트 훅이 생기기전인 Class Component에 대해 알아보자
클래스형컴포넌트와 함수형 컴포넌트
클래스컴포넌트 : rcc + enter
-componentDidMount
-UI 세팅이 마무리 되었을 때, 그 직후 실행
- 여기에서부터는 DOM 요소에 접근
- 무거운 데이터를 가져오는 API CAll
=> 왜? 가벼운 화면 렌더링이 끝나고 API CALL을 해야
사용자의 불쾌함이 줄어들기 때문이다.
클래스형 컴포넌트 실습
import React, { Component } from 'react'
/*
-class Component 단축키 : rcc + Enter
*/
export default class Ex13 extends Component {
// 랜더링 되기 전에 너 해야 할 거 써!
// 1번으로 사용
constructor(props){
/*생성자 함수 : 가장 먼저 실행되는 공간
-state값, 변수 값 초기화 하는 공간
-super(props)와 함께 사용하는 것을 권고하고 있음
밑에서 this 문법 사용 시, 생성자 내에서 정의되지 않아 버그 발생
*/
super(props);
this.state = {
counter : 0
} ;
// bind 함수 직접적으로 접근을 못하게 해서 간접적으로 접근할 수 있게
this.handleIncrement = this.handleIncrement.bind(this);
this.handleDecrement = this.handleDecrement.bind(this);
// 여기 안에 내가 원하는 함수를 넣어줌
}
// 증가 버튼
handleIncrement(){
console.log('handleIncrement Function');
this.setState({
counter : this.state.counter += 1
});
}
// 감소 버튼
handleDecrement(){
console.log(('handleDecrement Function'));
this.setState({
counter : this.state.counter -= 1
})
}
//2번째로 실행
render() {
return (
<div>
<h1>class
{/* this 안에 state가 있잖아 거기 안에 counter 쓸거야 */}
Counter : {this.state.counter}</h1>
<button onClick={this.handleIncrement}>+</button>
<button onClick={this.handleDecrement}>-</button>
</div>
)
}
}
다시 리액트 훅에 대해 알아보자
-기존에 사용하던 방식과 달리 함수형 프로그래밍으로 리액트롤 활용할 때, 쉽게 문법을 쓸 수 있도록 나온 기능
ex) use~
→ rafce로 가능
-함수 안에 있는 또 다른 함수
→ 특정 이벤트가 호출되었을 때 실행할 함수
.addEventListener( ’click’, ()⇒{} )
= componentDidMount
마찬가지로 API Call 같은 무거운 작업 시 많이 사용 된다!
=componentDidUpdate
값이 바뀌는 것을 인지해야 할 때 사용
정리!!
ClassComponent 에서는 시점을 지정할 수 있는
LifeCycle 이라는 게 존재 (Ex13.jsx)
=> Function Component(rafce)에서는 사용이 불 가능
대체 사용이 가능한 리액트 훅, useEffect를 사용
1) useEffect(함수,[])
- componentDidMount를 대체
- UI 세팅이 완료되어 DOM 접근 가능
- API Call
※주의사항!
-> 비어있더라도 Array[]는 꼭 적어줘야함
-> useEffect(함수)
모든 이벤트가 이뤄지는 것에 렌더링
2) useEffect(함수,[state])
- compomemtDidUpdate를 대체
- array 안에 있는 값이 갱신된 직후에 호출
- 최초 렌더링 때 한번 호출
-변화를 감지할 대상은 복수가 될 수도 있다.
함수형 컴포넌트 -콜백함수 참참참 게임
-useEffect 사용
문제 푸는 순서!
1. myChoice와comchoice 세팅 화면에 보옂기
2. pos 배열이 가지고 잇는 데이터 활용해서 세개의 베튼을 띄워줄것
3. 버튼 클릭 시, posRandom라는 함수실행
4. 버튼을 클릭한 값을 감지 ⇒ myChoice
난수를 받아와서 배열 안의 값 ⇒ comChoice
만약에, 판이 바뀔 때마다 myChoice, comChoice를 비교
-round라는 변수
-round 라는 값이 바뀔 때마다 승부 판정
useEffect는 첫번째 렌더링 될때는 무조건 실행된다..
import React, { useEffect, useState } from 'react'
const Ex15 = () => {
/*
나의 선택 : myChoice 0,1,2
상대방 수비 : comChoice 랜덤
결과 : result
상대방의 선택은 랜덤하게 결정
*/
let pos = ['왼쪽','정면','오른쪽']
console.log('pos',pos);
const [myChoice,setMyChoice] = useState('');
const [comChoice,setComChoice] = useState('');
const [result,setResult] = useState('게임 시작 전..');
// 몇판인지
const [round,setRound] = useState(0);
// comChoice 랜덤하게
const makeRandom = () =>{
return Math.floor(Math.random()*3);
}
//버튼 클릭시
const posRandom = (e) => {
// 몇 번째 판인지 버튼 클릭 시 1씩 증가!
setRound(round+1)
//나의 선택
console.log('나의 선택',e.target.innerText);
setMyChoice(e.target.innerText)
//상대방의 공격
// 0~2 난수를 추출 => pos안에 index로 작성
setComChoice(pos[makeRandom()])
}
//첫번째 렌더링은 무조건 실행 됨
useEffect(()=>{
// 0번째 판이 아닐 때 게임 진행
if(round!=0){
myChoice === comChoice
? setResult('승리')
: setResult('패배')
}
},[round])
return (
<div>
<h1> 참참참 게임</h1>
<p>나의 공격 : {myChoice}</p>
<p>상대방 수비 : {comChoice}</p>
<p>결과 : {result}</p>
<hr></hr>
{/* pos 배열에 맡게 map 세팅 */}
{/* key 값은 왼쪽 오른쪽 정면 그 자체로도 key값이 됨 */}
{pos.map(item => <button onClick={posRandom} key={item} >{item}</button>)}
</div>
)
}
export default Ex15