컴포넌트는
라이프사이클을 배우는 이유는 컴포넌트 인생 중간중간에 간섭할 수 있기 때문이다.
간섭이란 컴포넌트가 장착될 때 , 업데이트 될 때 등 특정 코드를 실행할 수 있다는 뜻이다.
“컴포넌트 등장 전에 이것 좀 해 줘”, “컴포넌트가 사라지기 전에 이것 좀 해 줘” 등 과 같이 코드 실행을 간섭하도록 갈고리(hook)를 달아 줄 수 있다.
class Detail2 extends React.Component {
componentDidMount(){
//Detail2 컴포넌트가 로드되고나서 실행할 코드
}
componentDidUpdate(){
//Detail2 컴포넌트가 업데이트 되고나서 실행할 코드
}
componentWillUnmount(){
//Detail2 컴포넌트가 삭제되기전에 실행할 코드
}
}
예전 class 문법을 사용할 당시 특정 훅을 사용했다.
근래엔 useEffect()
를 활용해 훅을 작성한다.
import {useState, useEffect} from 'react';
function Detail(){
useEffect(()=>{
//여기적은 코드는 컴포넌트 로드 & 업데이트 마다 실행됨
console.log('안녕')
});
return (생략)
}
useEffect() 안의 콜백 함수는 컴포넌트가 mount&update시 실행 된다.
<React.StrictMode>
위 훅의 console.log('안녕')
이 2번 출력 되는걸 알 수 있는데, 이는 디버깅용으로 2번 출력 되는 것이다.
이를 원하지 않는다면 index.js
파일에서 <React.StrictMode>
를 제거해 주면 된다.
console.log(’1’)
을 useEffect()
바깥에 적어도 mount & update 시 실행이 된다.
function Detail(){
useEffect(()=>{
});
console.log('안녕')
return (
// 생략
)
}
ㅋ컴포넌트가 mount, update시 function 안에 있는 코드도 다시 읽고 지나가기 때문이다.
그렇더면 useEffect는 왜 쓰는걸까?
useEffect 안에 적은 코드는 html 렌더링 이후에 동작한다.
아래 코드는 반복문을 실행하고 하단의 html을 렌더링해줄 것이다.
function Detail(){
(반복문 10억번 돌리는 코드)
return (생략)
}
반면,
function Detail(){
useEffect(()=>{
(반복문 10억번 돌리는 코드)
});
return (생략)
}
html을 렌더링하고 반복문을 돌릴 것이다.
이는 코드의 실행 시점을 조절해 html 렌더링이 조금 더 빠른 상황이 연출될 것이다.
Side Effect
함수의 핵심기능 외에 부가적인 기능들을 프로그래밍 용어로 side effect라고 하는데 useEffect도 여기에 차용하였다.
컴포넌트의 핵심 기능은 html렌더링이기 떄문에
그 외에 잡다한 오래 걸리는 반복 연산, 서버에서 데이터 가져오기, 타이머 등 부수적인 것들을 useEffect안에 작성 한다.
useEffect(()=> {
// 실행할코드
}, []);
useEffect()
의 둘째 파라미터로 []
가 올 수 있는데
변수나 state가 들어간다.
[ ]에 있는 변수나 state가 변경 될 때만 useEffect 안의 코드가 실행 된다.
[ ] 안이 공백이라면, 컴포넌트 mount시(로드 시) 1회 실행하고 재실행 하지 않는다.
useEffect가 동작하기 전에 특정 코드를 실행이 가능하다.
useEffect(() => {
console.log(2) // ------ (2)
return () => {
console.log(1) // ---- (1)
}
}, [])
return () ⇒ {}
안에 있는 1을 먼저 출력하고 다음으로 2가 출력이 된다.
가령, useEffect()
안에 setTimeOut()
가 있을 경우 컴포넌트가 마운트 될 때 마다 실행이 되는데 잘못 된 코드로 인해 무수히 많은 타이머가 생성이 될 수도 있다.
useEffect()
에서 타이머를 만들기 전에 기존의 타이머를 제거하는 코드를 짠다면 미연에 이를 방지할 수 있을 것이다.
useEffect(()=>{
let a = setTimeout(()=>{ setAlert(false) }, 2000)
return ()=>{
clearTimeout(a)
}
}, [])
💡 1. clean up function에는 타이머제거, socket 연결 요청제거, ajax요청 중단 등의 코드를 작성한다.
2. 컴포넌트 unmount 시 clean up function 내부가 1회 실행 된다.