
React를 사용하면서 가장 자주 사용되는 훅 중 하나인 useEffect에 대해 자세히 알아보겠습니다. 이 글에서는 useEffect의 호출 시점과 실제 사용 예시를 통해 효과적인 사용법을 설명합니다.
useEffect는 React의 핵심 훅 중 하나로, 컴포넌트의 생명주기와 관련된 부수 효과(side effects)를 처리하기 위해 사용됩니다. 데이터 페칭, 구독 설정, DOM 수동 조작 등 다양한 작업을 수행할 수 있습니다.
useEffect는 크게 세 가지 시점에서 호출됩니다:
컴포넌트가 처음 렌더링된 직후에 호출됩니다. 주로 다음과 같은 작업을 수행할 때 사용합니다:
useEffect(() => {
// 컴포넌트가 마운트될 때 실행될 코드
fetchData();
window.addEventListener('resize', handleResize);
// 클린업 함수
return () => {
window.removeEventListener('resize', handleResize);
};
}, []); // 빈 의존성 배열
의존성 배열에 지정된 값이 변경될 때마다 호출됩니다. 이때 중요한 점은:
useEffect(() => {
// count가 변경될 때마다 실행
console.log(`Count changed to: ${count}`);
return () => {
// 이전 count 값으로 클린업
console.log(`Cleaning up for count: ${count}`);
};
}, [count]); // count가 변경될 때마다 실행
컴포넌트가 제거될 때 클린업 함수가 실행됩니다. 메모리 누수를 방지하기 위해 중요한 시점입니다.
useEffect(() => {
const subscription = someAPI.subscribe();
return () => {
// 컴포넌트가 언마운트될 때 실행
subscription.unsubscribe();
};
}, []);
의존성 배열 관리
[]: 마운트/언마운트 시에만 실행무한 루프 방지
클린업 함수 활용
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let isMounted = true;
const fetchUser = async () => {
try {
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
if (isMounted) {
setUser(data);
setLoading(false);
}
} catch (error) {
if (isMounted) {
console.error('Error fetching user:', error);
setLoading(false);
}
}
};
fetchUser();
return () => {
isMounted = false;
};
}, [userId]);
if (loading) return <div>Loading...</div>;
if (!user) return <div>User not found</div>;
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}
useEffect는 React 컴포넌트에서 부수 효과를 다루는 강력한 도구입니다. 올바른 시점에 호출되고, 적절한 클린업을 수행하는 것이 중요합니다. 의존성 배열을 신중하게 관리하고, 클린업 함수를 활용하여 메모리 누수를 방지하는 것이 좋은 React 개발의 핵심입니다.