React useEffect 완벽 정리: 의존성 배열부터 클린업까지 이해하기
⚛️ React useEffect 완벽 정리: 의존성 배열부터 클린업까지 이해하기
React를 조금만 써보면 useEffect를 만나게 됩니다. 하지만 이 훅은 처음엔 조금 헷갈릴 수 있어요. 실행 시점, 의존성 배열, 클린업(cleanup) 등 알아야 할 개념이 많거든요.
이 글에서는 useEffect를 처음부터 끝까지 완벽하게 이해할 수 있도록 설명합니다. 실무에 바로 적용 가능한 팁도 함께 담았어요.
🔍 useEffect란?
useEffect
는 React에서 컴포넌트가 렌더링된 이후 실행되는 함수입니다. 비동기 통신, 타이머 설정, 이벤트 리스너 등록 등 부수 효과(side effect)를 처리할 때 사용돼요.
useEffect(() => {
// side effect (API 호출, 이벤트 등록 등)
}, []);
렌더링 이후에 실행된다는 점이 중요합니다. 즉, JSX가 화면에 나타난 다음 실행돼요.
🛠 기본 문법
useEffect(() => {
// 실행할 코드
}, [의존성1, 의존성2]);
- 첫 번째 인자: 실행할 콜백 함수
- 두 번째 인자: 의존성 배열 (Dependency Array)
이 배열에 어떤 값을 넣느냐에 따라 언제 useEffect가 실행될지가 결정됩니다.
📌 실행 시점에 따른 패턴 정리
① 마운트 시 1회 실행 (componentDidMount 역할)
useEffect(() => {
console.log('처음 한 번만 실행됨');
}, []);
의존성 배열이 빈 배열이면, 컴포넌트가 처음 화면에 나타날 때 딱 1번만 실행됩니다.
② 특정 값 변경 시 실행 (componentDidUpdate 역할)
useEffect(() => {
console.log('count가 변경될 때마다 실행');
}, [count]);
count
가 변경될 때마다 useEffect가 다시 실행됩니다.
③ 매 렌더링마다 실행
useEffect(() => {
console.log('렌더링마다 실행됨');
});
의존성 배열을 생략하면 컴포넌트가 리렌더링될 때마다 실행됩니다. 주의해서 사용해야 해요.
🧹 클린업 함수 (Cleanup)
useEffect는 리턴값으로 정리(cleanup) 함수를 가질 수 있어요. 이는 컴포넌트가 언마운트되거나, 의존성 값이 바뀌기 전에 실행됩니다.
✅ 예시: 타이머 정리
useEffect(() => {
const timer = setInterval(() => {
console.log('매 1초마다 실행');
}, 1000);
return () => {
clearInterval(timer); // 타이머 해제
};
}, []);
이렇게 하면 메모리 누수를 막고, 정리하는 시점을 명확히 관리할 수 있어요.
⚠️ useEffect에서 자주 하는 실수
- 의존성 배열 빠뜨리기: 필요한 변수를 빼먹으면 버그 발생 가능
- 무한 렌더링 발생: useEffect 안에서 setState → 다시 렌더 → 다시 실행 (주의!)
- 비동기 함수 직접 사용: useEffect 콜백에 async를 직접 쓰지 말 것
❌ 잘못된 예
useEffect(async () => {
const res = await fetch(...); // 비추천
}, []);
✅ 올바른 예
useEffect(() => {
async function fetchData() {
const res = await fetch(...);
// 처리
}
fetchData();
}, []);
비동기 함수는 내부에서 따로 정의해서 호출해야 합니다.
📊 실무에서 자주 쓰는 패턴
① API 호출
useEffect(() => {
fetch('/api/data')
.then(res => res.json())
.then(data => setData(data));
}, []);
② 이벤트 리스너 등록 & 정리
useEffect(() => {
const handleResize = () => console.log(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
③ 외부 상태 감지 (예: redux or props)
useEffect(() => {
console.log('로그인 상태 변경됨:', isLoggedIn);
}, [isLoggedIn]);
→ 의존성 배열은 해당 값이 변경될 때만 실행되도록 제어하는 게 핵심입니다.
📚 useEffect 관련 추천 리소스
✅ 마무리 정리
- useEffect는 부수 효과를 처리하는 훅이다.
- 의존성 배열을 통해 실행 조건을 제어할 수 있다.
- 클린업 함수는 정리 작업에 반드시 필요하다.
- 렌더링마다 실행되는 경우는 신중하게 써야 한다.
처음엔 복잡해 보일 수 있지만, 의존성 배열과 클린업만 잘 이해하면 useEffect는 정말 강력한 도구입니다.
useEffect는 React 앱의 '자동화 스크립트' 같은 존재입니다.
상태 변화에 따라 어떤 로직을 자동으로 실행시킬지 선언하세요.
다음 글에서는 useEffect의 고급 패턴이나 React 컴포넌트 생명주기와의 연계를 다뤄보겠습니다!