1. 컴포넌트의 Lifecycle
- 생성이 될 수도 있고 (전문용어로 mount)
컴포넌트가 브라우저에 보여지면 mount 된다고 한다
- 재렌더링이 될 수도 있고 (전문용어로 update)
컴포넌트 안에서 state 같은걸 조작했을 때
- 삭제가 될 수도 있다. (전문용어로 unmount)
<이거를 왜 배울까?>
lifecycle을 알고 있으면 과정 중간중간에 간섭(코드실행) 할 수 있다.
컴포넌트가 장착될때 특정 코드를 실행할 수도 있고,
컴포넌트가 업데이트될 때 특정 코드를 실행할 수도 있다.
그러면 재밌는 기능을 개발할 수 있다.
<요즘 React에서 Lifecycle hook 쓰는법>
import {useEffect} from 'react';
// 상단에서 useEffect import 해오고
function Detail(){
// useEffect()안에 콜백함수 추가.
useEffect(()=>{
//여기적은 코드는 컴포넌트 로드 & 업데이트 마다 실행됨
console.log('안녕')
// 안녕이 2번 출력되는데 리액트 환경에선 원래 그럼.
// 디버깅용으로 편하라고 2번 출력해주는거임.
// 이게 싫다면 index.html로 가서 <React.StrictMode> 없애면 된다.
});
return (생략)
}
function Detail(props){
console.log('안녕') // 바깥에서도 안에 적은 것과 같이 실행이 되는데?...
useEffect(()=>{
});
function Detail(props){
useEffect(()=>{
console.log('안녕')
// useEffect 안에 적은 코드는 렌더링이 다 되고나서 실행이 된다.(즉 가장 마지막에 실행된다.)
});
function Detail(props){
useEffect(()=>{
});
// 복잡한 연산을 해줘야 한다고 가정해보자
for(let i = 0; i < 10000; i++){
console.log(1);
}
}
위의 코드는 어떤식으로 동작하냐면 Detail 컴포넌트가 필요해졌을 때 JS는 위에서 부터 코드를 차례로 읽기 때문에 for 반복문 부터 읽게된다.
그런데 for 반복문 실행하는데 엄청 오래걸리기 때문에 비효율적인데 이 오래걸리는 작업을 useEffect에 넣게되면 가장 마지막에 읽기 때문에 효율적이다.
(정확한 실행 시점은 return( )안에 있는 html 코드들이 랜더링 된 후에 실행 된다)
어려운 연산(시간이 오래걸리는 작업)
서버에서 데이터 가져오는 작업
타이머가 필요할때
📑 컴포넌트의 핵심 기능은 html랜더링이라 그거 외의 기능들은 useEffect 안에 적으면 된다.
useEffect에 둘째 파라미터로 [ ]을 넣을 수 있는데 그곳에 변수나 state같은 것들을 넣을 수 있다.
그렇게 하면 [ ]에 있는 변수나 state가 변할 때만 useEffect 안의 코드를 실행해준다.
(참고. [ ] 안에 state 여러 개 넣을 수 있다)
아래와 같이 아무것도 넣지 않으면 컴포넌트 mount시(로드시) 1회 실행하고 영영 실행해주지 않는다.
let [count, setCount] = useState(0);
useEffect(() => { 실행할코드 }, [count])
// mount될때랑 count라는 state가 update될 때마다 실행된다.
useEffect(() => { 실행할코드 }, [])
// 디펜던시가 비어있으면 mount시에만 실행되고 update시에는 실행되지 않는다.
useEffect 동작하기 전에 특정코드를 실행하고 싶으면 아래와 같이 작성하면 된다.
이런걸 clean up function이라 한다.
useEffect(()=>{
// (2) .. 그 다음 실행됨
return ()=>{
// (1) .. 먼저 실행됨
}
}, []);
useEffect 안에 있는 코드를 실행할 때 치우고 깔끔한 상태로 실행하기 위해 존재한다.
useEffect(()=>{
let a = setTimeout(()=>{~~~~~},2000)
return ()=>{
clearTimeout(a)
}
}, [])
useEffect(()=>{
// 서버로 데이터 요청하는 코드(2~3초 소요)
return ()=>{
// 기존 데이터 요청은 제거해주세요.
}, [])
데이터 요청하는데 2~3초가 걸린다면 그 사이에 재렌더링이 될 수도 있고 그렇게되면 계속해서 요청하는 코드가 실행이 될 것이고 버그도 발생할 것이다.
이럴 때도 cleanup 함수를 사용한다.
♨️결론
1. 재렌더링마다 코드 실행가능.
useEffect(()=>{ 실행할코드 })
2. 컴포넌트 mount시 1회만 실행가능.
useEffect(()=>{ 실행할코드 }, [])
3. useEffect 안의 코드 실행 전에 항상 실행됨.
useEffect(()=>{
return ()=>{
실행할코드
}
})
4. 컴포넌트 unmount시 1회 실행됨.
useEffect(()=>{
return ()=>{
실행할코드
}
}, [])
5. state1이 변경될 때만 실행됨.
useEffect(()=>{
실행할코드
}, [state1])
출처. 코딩애플