React 기초 07 · useEffect
useEffect - 화면 바뀐 뒤 할 일
화면을 다 그린 뒤 실행되는 뒷정리 담당. 언제 다시 실행되는지(의존성)와 cleanup이 왜 필요한지 타임라인으로 봐요.
1
먼저 비유로
일 끝내고 하는 뒷정리예요
React가 화면을 다 그리고 나면, "이제 그렸으니 할 일 있으면 해" 하고 useEffect를 실행해요. 데이터 가져오기, 타이머 켜기, 이벤트 구독 같은 화면 밖의 일이 여기 들어가요. 그리고 다음에 다시 하기 전이나 컴포넌트가 사라질 때는 cleanup(뒷정리)으로 켜둔 걸 꺼야 해요. 안 그러면 타이머가 계속 쌓여요.
언제 다시 실행할지는 의존성 배열(deps)로 정해요. [count]면 count가 바뀔 때마다, []면 처음 한 번만 실행돼요.
2
직접 해보기
실행 순서를 타임라인으로
count +1과 다시 마운트를 눌러보고, 아래 로그에서 effect(초록)와 cleanup(분홍)이 어떤 순서로 찍히는지 보세요. deps를 처음 한 번만으로 바꾸면 count +1을 눌러도 effect가 안 도는 걸 확인하세요.
직접 만져보세요
화면 속 count0
effect를 언제 다시 실행할까 (deps)
count +1 또는 다시 마운트를 눌러 effect가 도는 걸 보세요.
'처음 한 번만'에선 count +1을 눌러도 effect가 안 도는 걸 보세요. (개발 모드라 첫 실행이 두 번 찍힐 수 있어요 - 배포본은 한 번이에요.)
deps 모드를 바꿔가며 count +1을 눌러 차이를 비교하세요.
핵심은 이거예요
useEffect는 화면을 그린 뒤 실행되는 "화면 밖의 일" 담당이에요. deps로 언제 다시 돌지 정하고, 켠 건 cleanup으로 반드시 꺼주세요.
3
흐름으로 보기
effect와 cleanup의 순서
- 1state가 바뀌면 컴포넌트가 다시 그려져요(렌더).
- 2화면이 실제로 반영된 뒤, deps가 바뀌었으면 React가 effect를 실행해요.
- 3다시 실행하기 전에는, 먼저 지난번 cleanup을 호출해 옛 작업을 정리해요.
- 4컴포넌트가 화면에서 사라질 때도 cleanup이 한 번 불려 마지막 정리를 해요.
4
코드로 보기
딱 이만큼이에요
function Timer() { const [count, setCount] = useState(0); useEffect(() => { // 화면을 다 그린 뒤 실행됨 (예: 타이머 시작, 데이터 가져오기) const id = setInterval(() => console.log("째깍"), 1000); // cleanup: 다음 실행 전 / 사라질 때 뒷정리 (안 하면 타이머가 쌓임) return () => clearInterval(id); }, []); // [] = 처음 한 번만. [count] 면 count 바뀔 때마다. return <p>{count}</p>;}5
조심하세요
처음에 꼭 헷갈리는 것
- deps를 빼먹기. deps 배열 자체를 안 쓰면 매 렌더마다 실행돼요. 그 안에서 setState까지 하면 무한 반복에 빠질 수 있어요.
- cleanup을 안 하기. 타이머·구독·이벤트는 return으로 꼭 정리하세요. 안 하면 중복 실행·메모리 누수가 생겨요.
- 개발 모드의 두 번 실행에 당황하기. StrictMode가 점검하느라 처음에 effect를 두 번 돌려요. 버그가 아니고, 배포본에선 한 번이에요.