컴포넌트의 Lifecycle 을 배우는 이유는 componentDidMount() 등 유용한 Lifecycle 함수들을 쓰기 위해서이다.
요즘은 간편한 useEffect() 라는 react hook 을 많이 사용한다.
컴포넌트의 Lifecycle
컴포넌트는
1. 생성 될 수도 있고 (mount)
2. 재렌더링 될 수도 있고 (update)
3. 삭제될 수도 있다. (unmount)
컴포넌트의 lifecycle 을 배우는 이유는 컴포넌트 lifecycle 중간중간에 간섭할 수 있기 때문이다.
컴포넌트가 장착될 때 특정 코드를 실행할 수도 있고, 컴포넌트 업데이트 될 때 특정 코드를 실행할 수도 있다.
이러한 방법으로 여러 기능들을 개발할 수 있다.
예전 React 에서 Lifecycle Hook 쓰는 법
class Detail2 extends React.Component {
componentDidMount(){
//Detail2 컴포넌트가 로드되고나서 실행할 코드
}
componentDidUpdate(){
//Detail2 컴포넌트가 업데이트 되고나서 실행할 코드
}
componentWillUnmount(){
//Detail2 컴포넌트가 삭제되기전에 실행할 코드
}
}
예전에는 class 문법으로 컴포넌트를 만들어주었다.
그 경우엔 안에 함수안에서 실행하고싶은 코드를 작성하여 코드를 실행시킬 수 있다.
요즘 React 에서 Lifecycle Hook 쓰는 법
import { useState, useEffect } from 'react';
function Detail(){
useEffect(()=> {
// 여기 적은 코드는 컴포넌트 로드 & 업데이트 될 때마다 실행됨
console.log('안녕')
})
return 생략..
}
상단에 useEffect import 해준 후,
콜백함수 추가해서 안에 코드 작성하면 해당 코드는 컴포넌트가 mount & update 시 실행된다.
이것이 Lifecycle Hook
그런데 useEffect 밖에서 코드 적어도 똑같은 결과
사실 useEffect 밖에 적어도 똑같이 컴포넌트 mount & update 시 실행된다.
컴포넌트가 재렌더링 시 function 안에 있던 코드들도 다시 읽고 지나가서 그렇다.
그럼 useEffect 는 무슨 용도일까
useEffect 안에 작성한 코드는 html 렌더링 이후에 작동한다.
예를들어 시간이 굉장히 오래 걸리는 코드가 있다고 가정하자.
function Detail(){
(반복문 100000000번 돌리는 코드)
return (생략)
}
위와같이 코드를 짜게되면 반복문을 많이 돌린 후, 하단 return 문의 html 을 보여준다.
function Detail(){
useEffect(()=>{
(반복문 100000000 돌리는 코드)
});
return (생략)
}
하지만 useEffect 를 사용하면 html 보여주고 나서 반복문을 돌려준다.
이런 식으로 코드의 실행 시점을 조절할 수 있기 때문에 조금이라도 html 렌더링이 빠른 페이지를 원하면, 쓸데 없는 (반복문 많이 돌리기) 코드들은 useEffect 안에 넣어서 사용하는 것이 좋다.
오래걸리는 반복연산, 서버에서 데이터 가져오는 작업, 타이머 달기 등
이런 코드들은 useEffect 안에 많이 적는다.
useEffect 에 넣을 수 있는 실행조건
useEffect(()=>{실행할 코드}, [count])
useEffect() 의 두번째 파라미터로 [] 를 넣을 수 있는데, 거기에 변수나 state 같은 것들을 넣어줄 수 있다.
위와 같이 작성하면 [] 에 있는 변수나 state 가 변할 때만 useEffect 안의 코드를 실행해준다.
따라서 위의 코드는 count 라는 변수가 변할 때만 안의 코드가 실행된다.
[] 안에는 state 변수를 여러 개 넣어줄 수도 있다.
useEffect(()=>{실행할 코드}, [])
위처럼 [] 안에 아무것도 넣지 않으면 컴포넌트 mount 시 (로드 시) 한번만 실행해준다.
clean up function
useEffect 동작하기 전에 특정 코드를 실행시키고 싶으면
return () => {} 안에 넣어주면 된다.
useEffect(()=>{
//그 다음 실행
return ()=>{
//여기 먼저 실행
}
}, []);
useEffect 안에 있는 코드를 실행하기 전에 return 함수 안에 있는 코드를 먼저 실행해준다.
setTimeout 함수의 경우
setTimeout() 쓸 때마다 브라우저 안에 타이머가 하나 생긴다. 근데 useEffect 안에 작성했기 때문에 컴포넌트가 mount 될 때마다 실행된다.
코드를 잘못 짜게 되면 타이머가 100개, 1000개 이상하게 생길 수 있다.
따라서, 이런 버그를 미리 방지하기 위해서 useEffect 에서 타이머를 만들기 전에 기존 타이머를 제거하라고 코드 쓰면 되는데, 이럴때 return ()=>{} 안에 짜준다.
useEffect(()=>{
let a = setTimeout(()=>{
setAlert(false);
}, 2000);
return ()=>{
clearTimeout(a);
}
})
타이머를 제거해주고 싶다면, clearTimeout(타이머) 이런식으로 작성해준다.
타이머 장착하기 전에 기존 타이머가 있으면 제거해준다.
- clean up function 에는 타이머제거, socket 연결요청제거, ajax 요청 중단 등.. 이런 코드를 많이 작성해준다.
- 컴포넌트 unmount 시에도 clean up function 안에 있던 게 1회 실행된다.
1. 재렌더링 할 때마다 코드 실행 가능
useEffect(()=>{ 실행할 코드 })
2. 컴포넌트 mount 시 (로드 시) 1회만 실행 가능
useEffect(()=>{ 실행할 코드 }, [])
3. useEffect 안의 코드 실행 전에 항상 실행
useEffect(()=>{
return ()=>{
실행할코드
}
})
4. 컴포넌트 unmount 시 1회 실행
useEffect(()=>{
return ()=>{
실행할코드
}
}, [])
5. state 이 변경될 때만 실행
useEffect(()=>{
실행할코드
}, [state1])
'React' 카테고리의 다른 글
Context API (0) | 2023.03.07 |
---|---|
Ajax 요청 (0) | 2023.03.07 |
React Router (navigate, nested routes, outlet), useParams (0) | 2023.02.25 |
React Router (0) | 2023.02.17 |
export / import (0) | 2023.02.17 |