Lifecycle이란?
React의 컴포넌트는 생명 주기가 있습니다. 생애 주기 또는 라이프사이클(Life cycle)이라고도 많이 표현합니다.
컴포넌트는
1. 생성이 될 수도 있고 (전문용어로 mount)
2. 재렌더링이 될 수도 있고 (전문용어로 update)
3. 삭제가 될 수도 있습니다. (전문용어로 unmount)
저희가 라이프사이클에 대해서 배우는 이유는 컴포넌트 인(라이프사이클)에 간섭할 수 있기 때문입니다.
간섭이 뭐냐면 그냥 코드실행인데 컴포넌트가 장착이 될 때 특정 코드를 실행할 수도 있고 컴포넌트가 업데이트될 때 특정 코드를 실행할 수도 있다는 겁니다.
인생에 간섭하는 방법
"Detail 컴포넌트 등장 전에 이것좀 해줘"
"Detail 컴포넌트 사라지기 전에 이것좀 해줘"
"Detail 컴포넌트 업데이트 되고나서 이것좀 해줘"
이렇게 코드좀 실행해달라고 간섭할 수 있는데, 간섭은 갈고리를 달아서 합니다.
갈고리를 달아서 코드를 넣어주면 됩니다.
그럼 진짜 페이지 장착시, 업데이트시, 제거시 코드실행가능
갈고리는 영어로 hook이라고 합니다. 그래서 저걸 Lifecycle hook 이라고 부릅니다.
React에서 Lifecycle hook 쓰는 법 : useEffect
import {useState, useEffect} from 'react';
function Detail(){
useEffect(()=>{
//여기적은 코드는 컴포넌트 로드 & 업데이트 마다 실행됨
console.log('안녕')
});
return (생략)
}
상단에서 useEffect import해오고
콜백함수 추가해서 안에 코드 적으면 이제 그 코드는 컴포넌트가 mount & update시 실행됩니다.
그래서 이게 Lifecycle hook 입니다.
import {useState, useEffect} from 'react';
function Detail(){
useEffect(()=>{
//여기적은 코드는 컴포넌트 로드 & 업데이트 마다 실행됨
console.log('안녕')
});
let [count, setCount] = useState(0)
return (
<button onClick={()=>{ setCount(count+1) }}>버튼</button>
)
}
재렌더링시(state 업데이트)에도 진짜 '안녕' 출력되나 테스트해보려고 버튼누르면 재렌더링되게 코드짜봤습니다. 버튼눌러서 실험해봅시다.
참고로 console에 '안녕' 2번 출력될텐데 index.js에 <React.StrictMode>라는 태그가 있으면 2번 출력해줍니다. 디버깅용으로 편하라고 2번 출력해주는데 싫으면 저 태그를 제거하거나 그럽시다.
근데 useEffect 밖에 적어도 똑같은데요
실은 useEffect 바깥에 적어도 똑같이 컴포넌트 mount & update시 실행됩니다.
컴포넌트가 mount & update시 function 안에 있는 코드도 다시 읽고 지나가서 그렇습니다.
그럼 대체 useEffect 왜 만들어놓은 것일까요?
useEffect 안에 적은 코드는 html 렌더링 이후에 동작합니다.
그럼 이제 useEffect가 뭔가 유용할 것 같지 않습니까
예를 들어서 굉장히 시간이 오래걸리는 쓸데없는 코드가 필요하다고 가정해봅시다.
function Detail(){
(반복문 10억번 돌리는 코드)
return (생략)
}
▲ 여기에 대충 적으면 반복문 돌리고 나서 하단의 html 보여줌
function Detail(){
useEffect(()=>{
(반복문 10억번 돌리는 코드)
});
return (생략)
}
▲ useEffect 안에 적으면 html 보여주고 나서 반복문 돌림
이런 식으로 코드의 실행 시점을 조절할 수 있기 때문에 조금이라도 html 렌더링이 빠른 사이트를 원하면 쓸데없는 것들은 useEffect 안에 넣어보길 바랍니다.
오래걸리는 반복연산, 서버에서 데이터가져오는 작업, 타이머다는거 이런건 useEffect 안에 많이 적습니다.
useEffect에 넣을 수 있는 실행조건
useEffect(()=>{ 실행할코드 }, [count])
useEffect()의 둘째 파라미터로 [ ] 를 넣을 수 있는데, 거기에 변수나 state같은 것들을 넣을 수 있습니다.
- 그렇게 하면 [ ]에 있는 변수나 state 가 변할 때만 useEffect 안의 코드를 실행해줍니다.
- 그래서 위의 코드는 count라는 변수가 변할 때만 useEffect 안의 코드가 실행합니다.
(참고) [ ] 안에 state 여러개 넣을 수 있음
useEffect(()=>{ 실행할코드 }, [])
아무것도 안넣으면 컴포넌트 mount시 (로드시) 1회 실행하고 영영 실행해주지 않습니다.
clean up function
useEffect 동작하기 전에 특정코드를 실행하고 싶으면 return ()=>{} 안에 넣을 수 있습니다.
useEffect(()=>{
그 다음 실행됨
return ()=>{
여기있는게 먼저실행됨
}
}, [count])
그럼 useEffect 안에 있는 코드를 실행하기 전에 return ()=>{ } 안에 있는 코드를 실행해줍니다.
참고로 저걸 clean up function 이라고 부릅니다.
clean up function이 존재하는 이유는
useEffect 안에 있는 코드를 실행할 때도 싹 치우고 깔끔한 마음으로 실행하는게 좋을 때가 있습니다.
예를 들면 setTimeout 타이머인데, setTimeout() 쓸 때마다 브라우저 안에 타이머가 하나 생깁니다.
근데 useEffect 안에 썼기 때문에 컴포넌트가 mount 될 때 마다 실행됩니다.
그럼 잘못 코드를 짜면 타이머가 100개 1000개 생길 수도 있겠군요.
나중에 그런 버그를 방지하고 싶으면useEffect에서 타이머 만들기 전에 기존 타이머를 싹 제거하라고 코드를 짜면 되는데 그런거 짤 때 return ()=>{} 안에 짜면 됩니다.
useEffect(()=>{
let a = setTimeout(()=>{ setAlert(false) }, 2000)
return ()=>{
clearTimeout(a)
}
}, [])
타이머 제거하고 싶으면 clearTimeout(타이머) 이렇게 코드짜면 됩니다.
(참고1) clean up function에는 타이머제거, socket 연결요청제거, ajax요청 중단 이런 코드를 많이 작성합니다.
(참고2) 컴포넌트 unmount 시에도 clean up function 안에 있던게 1회 실행됩니다.
출처 : 코딩애플 "React 리액트 기초부터 쇼핑몰 프로젝트까지!"
'React' 카테고리의 다른 글
리액트 React : 컴포넌트 전환 애니메이션 주는 법 (transition) (0) | 2024.03.28 |
---|---|
리액트 React : 리액트에서 탭 UI 만들기 (0) | 2024.03.27 |
리액트 React : styled-components (0) | 2024.03.26 |
리액트 React : 리액트 라우터(react-router) (0) | 2024.03.26 |
리액트 React : Module, import 및 export (0) | 2024.03.25 |