레슨 4 / 9·20분
useEffect와 사이드 이펙트
useEffect란?
useEffect는 컴포넌트가 렌더링된 후 실행되는 사이드 이펙트(데이터 fetching, DOM 조작, 구독 등)를 처리하는 Hook입니다. 의존성 배열로 실행 시점을 제어합니다.
tsx
import { useState, useEffect } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
// 마운트 시 타이머 시작, 언마운트 시 정리
useEffect(() => {
const id = setInterval(() => {
setSeconds(prev => prev + 1);
}, 1000);
// 클린업 함수 — 컴포넌트 제거 시 실행
return () => clearInterval(id);
}, []); // 빈 배열 = 마운트 시 1회만 실행
return <p>경과 시간: {seconds}초</p>;
}의존성 배열
- •
useEffect(fn)— 매 렌더링마다 실행 (거의 사용 안 함) - •
useEffect(fn, [])— 마운트 시 1회만 실행 - •
useEffect(fn, [a, b])— a 또는 b가 변경될 때 실행
tsx
function UserProfile({ userId }: { userId: string }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
// userId가 변경될 때마다 데이터 다시 가져오기
useEffect(() => {
setLoading(true);
fetch("/api/users/" + userId)
.then(res => res.json())
.then(data => {
setUser(data);
setLoading(false);
});
}, [userId]); // userId 변경 시 재실행
if (loading) return <p>로딩 중...</p>;
if (!user) return <p>사용자를 찾을 수 없습니다.</p>;
return (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
);
}클린업 함수
useEffect에서 반환하는 함수는 클린업(정리) 함수입니다. 이벤트 리스너 해제, 타이머 정리, 구독 취소 등에 사용됩니다. 컴포넌트가 언마운트되거나 의존성이 변경되기 전에 실행됩니다.
tsx
function WindowSize() {
const [size, setSize] = useState({
width: window.innerWidth,
height: window.innerHeight,
});
useEffect(() => {
const handleResize = () => {
setSize({
width: window.innerWidth,
height: window.innerHeight,
});
};
window.addEventListener("resize", handleResize);
// 클린업: 이벤트 리스너 제거
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
return (
<p>
창 크기: {size.width} x {size.height}
</p>
);
}💡
React 18의 Strict Mode에서는 개발 환경에서 useEffect가 두 번 실행됩니다. 이는 클린업 함수가 올바르게 작동하는지 검증하기 위한 의도적 동작이며, 프로덕션에서는 한 번만 실행됩니다.