React Hook useEffect has a missing dependency 에러 완벽 해결 가이드
도입: React Hook useEffect has a missing dependency 에러란?
🔗 관련 에러 해결 가이드
React 개발 중 ‘React Hook useEffect has a missing dependency’ 경고를 만나본 적이 있나요? 이 경고는 React 개발자들이 가장 자주 마주치는 경고 메시지 중 하나입니다. useEffect 훅을 사용할 때 의존성 배열(dependency array)에 필요한 값을 누락했을 때 발생하며, ESLint의 exhaustive-deps 규칙이 이를 감지합니다. 이 경고를 무시하면 예상치 못한 버그와 성능 문제가 발생할 수 있습니다. 이 글에서는 ‘React Hook useEffect has a missing dependency’ 에러의 원인부터 해결 방법, 그리고 예방법까지 모든 것을 상세히 다룹니다.
🤖 AI 에러 분석 도우미
이 에러는 다음과 같은 상황에서 주로 발생합니다:
- 코드 문법 오류가 있을 때
- 라이브러리나 의존성 문제
- 환경 설정이 잘못된 경우
- 타입 불일치 문제
💡 위 해결법을 순서대로 시도해보세요. 90% 이상 해결됩니다!
에러 상세 분석
이 경고 메시지는 React의 린터 규칙인 react-hooks/exhaustive-deps가 useEffect, useCallback, useMemo 등의 훅에서 사용되는 값들이 의존성 배열에 제대로 포함되어 있는지 검사할 때 나타납니다. 전체 경고 메시지는 다음과 같은 형태로 표시됩니다:
React Hook useEffect has a missing dependency: 'functionName'.
Either include it or remove the dependency array. (react-hooks/exhaustive-deps)
이 경고가 발생하는 근본적인 이유는 React의 클로저(closure) 특성과 관련이 있습니다. useEffect 내부에서 사용하는 props, state, 또는 함수가 의존성 배열에 없으면, 해당 값들은 useEffect가 처음 생성될 때의 오래된 값을 계속 참조하게 됩니다. 이를 ‘stale closure’ 문제라고 하며, 예상치 못한 동작의 주요 원인이 됩니다. React는 이러한 문제를 방지하기 위해 의존성 배열을 엄격하게 관리하도록 권장합니다.
발생 원인 5가지
1. Props나 State를 의존성 배열에 누락
가장 흔한 원인으로, useEffect 내부에서 사용하는 props나 state 값을 의존성 배열에 포함시키지 않은 경우입니다. 컴포넌트가 리렌더링될 때 새로운 값이 전달되어도 useEffect는 이를 감지하지 못해 오래된 값을 계속 사용하게 됩니다.
2. 함수를 의존성 배열에서 제외
useEffect 내부에서 호출하는 함수를 의존성 배열에 포함시키지 않으면 경고가 발생합니다. 특히 컴포넌트 내부에 정의된 함수는 매 렌더링마다 새로 생성되므로 반드시 의존성으로 관리해야 합니다.
3. 객체나 배열을 직접 참조
객체나 배열은 참조 타입이므로 매 렌더링마다 새로운 참조를 생성합니다. 이를 의존성 배열에 직접 포함하면 불필요한 useEffect 실행을 유발할 수 있지만, 포함하지 않으면 경고가 발생합니다.
4. useCallback이나 useMemo로 감싸지 않은 함수
컴포넌트 내부에서 정의한 함수를 useEffect에서 사용할 때, 해당 함수를 useCallback으로 메모이제이션하지 않으면 매번 새로운 함수가 생성되어 의존성 문제가 발생합니다.
5. 외부 변수나 모듈 함수 사용
컴포넌트 외부에서 선언된 변수나 import한 함수를 사용할 때도 경고가 나타날 수 있습니다. 이는 해당 값이 변경될 가능성이 있는지 React가 판단할 수 없기 때문입니다.
해결방법 7가지 (코드 포함)
해결법 1: 의존성 배열에 누락된 값 추가
가장 기본적이고 권장되는 방법입니다. useEffect 내부에서 사용하는 모든 값을 의존성 배열에 포함시킵니다.
// 문제가 있는 코드
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser(userId).then(setUser);
}, []); // userId가 누락됨
return {user?.name};
}
// 올바른 코드
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser(userId).then(setUser);
}, [userId]); // userId를 의존성 배열에 추가
return {user?.name};
}
해결법 2: useCallback으로 함수 메모이제이션
컴포넌트 내부 함수를 useCallback으로 감싸서 불필요한 재생성을 방지합니다.
function TodoList({ filter }) {
const [todos, setTodos] = useState([]);
// useCallback으로 함수 메모이제이션
const fetchTodos = useCallback(async () => {
const data = await getTodos(filter);
setTodos(data);
}, [filter]);
useEffect(() => {
fetchTodos();
}, [fetchTodos]); // 이제 fetchTodos를 안전하게 의존성에 포함
return {todos.map(todo => - {todo.text}
)}
;
}
해결법 3: 함수를 useEffect 내부로 이동
함수를 useEffect 내부에 정의하면 의존성 배열 문제를 간단히 해결할 수 있습니다.
function DataFetcher({ apiUrl, params }) {
const [data, setData] = useState(null);
useEffect(() => {
// 함수를 useEffect 내부로 이동
async function fetchData() {
const response = await fetch(`${apiUrl}?${new URLSearchParams(params)}`);
const result = await response.json();
setData(result);
}
fetchData();
}, [apiUrl, params]); // 함수 대신 실제 값만 의존성에 추가
return {JSON.stringify(data)};
}
해결법 4: 함수형 업데이트 사용
setState의 함수형 업데이트를 사용하면 현재 state를 의존성 배열에서 제거할 수 있습니다.
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
// 함수형 업데이트 사용 - count를 의존성에서 제거 가능
setCount(prevCount => prevCount + 1);
}, 1000);
return () => clearInterval(timer);
}, []); // count가 없어도 정상 작동
return Count: {count};
}
해결법 5: useRef로 최신 값 참조
의존성 배열에 포함시키지 않으면서도 최신 값을 참조해야 할 때 useRef를 사용합니다.
function ChatRoom({ roomId, onMessage }) {
const onMessageRef = useRef(onMessage);
// 최신 콜백을 ref에 저장
useEffect(() => {
onMessageRef.current = onMessage;
}, [onMessage]);
useEffect(() => {
const socket = connectToChat(roomId);
socket.on('message', (msg) => {
// ref를 통해 최신 콜백 호출
onMessageRef.current(msg);
});
return () => socket.disconnect();
}, [roomId]); // onMessage를 의존성에서 제외 가능
return Chat Room: {roomId};
}
해결법 6: useMemo로 객체/배열 메모이제이션
객체나 배열을 의존성으로 사용할 때 useMemo로 안정적인 참조를 유지합니다.
function ProductList({ category, sortBy }) {
const [products, setProducts] = useState([]);
// 옵션 객체를 useMemo로 메모이제이션
const fetchOptions = useMemo(() => ({
category,
sortBy,
limit: 20
}), [category, sortBy]);
useEffect(() => {
fetchProducts(fetchOptions).then(setProducts);
}, [fetchOptions]); // 안정적인 참조 유지
return {products.length} products;
}
해결법 7: ESLint 규칙 비활성화 (최후의 수단)
정말 필요한 경우에만 특정 라인에서 ESLint 규칙을 비활성화합니다. 이 방법은 권장되지 않으며, 사용 시 충분한 주석을 추가해야 합니다.
function SpecialCase() {
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
// 특별한 이유로 의존성 규칙을 무시해야 하는 경우
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); // 주의: 이 방법은 최후의 수단으로만 사용
return {mounted ? 'Mounted' : 'Loading'};
}
예방법과 베스트 프랙티스
1. ESLint 설정 활성화: react-hooks/exhaustive-deps 규칙을 프로젝트에 활성화하여 경고를 실시간으로 확인하세요.
2. 의존성 배열 자동 수정: VS Code의 Quick Fix 기능을 사용하면 누락된 의존성을 자동으로 추가할 수 있습니다.
3. 커스텀 훅 분리: 복잡한 로직은 커스텀 훅으로 분리하여 의존성 관리를 단순화하세요.
4. 함수 선언 위치 고려: 가능하면 함수를 useEffect 내부나 컴포넌트 외부에 선언하여 의존성 문제를 줄이세요.
5. 정기적인 코드 리뷰: useEffect 사용 시 팀원들과 코드 리뷰를 통해 의존성 배열이 올바른지 검증하세요.
마무리
React Hook useEffect has a missing dependency 경고는 단순한 경고가 아닌 잠재적인 버그를 예방하는 중요한 신호입니다. 이 글에서 소개한 7가지 해결 방법을 상황에 맞게 적용하면 대부분의 의존성 문제를 해결할 수 있습니다. 가장 중요한 것은 의존성 배열의 원리를 이해하고, ESLint의 경고를 무시하지 않는 것입니다. 올바른 의존성 관리는 예측 가능하고 안정적인 React 애플리케이션을 만드는 기초입니다. 오늘부터 의존성 배열을 정확히 관리하여 더 견고한 React 코드를 작성해보세요!
📚 함께 읽으면 좋은 글
Cannot read properties of undefined (reading ‘map’) 완벽 해결법 – 원인부터 예방까지
📅 2025. 11. 19.
🎯 Cannot read properties of undefined (reading ‘map’)
Cannot read properties of undefined (reading ‘map’) 완벽 해결법 – 원인부터 예방까지
📅 2025. 11. 18.
🎯 Cannot read properties of undefined (reading ‘map’)
Warning: Each child in a list should have a unique “key” prop 완벽 해결법 – 원인부터 예방까지
📅 2025. 11. 17.
🎯 Warning: Each child in a list should have a unique “key” prop
React Hook useEffect has a missing dependency 완벽 해결법 – 원인부터 예방까지
📅 2025. 11. 17.
🎯 React Hook useEffect has a missing dependency
React Hook useEffect has a missing dependency 완벽 해결법 – 원인부터 예방까지
📅 2025. 11. 17.
🎯 React Hook useEffect has a missing dependency
💡 위 글들을 통해 더 깊이 있는 정보를 얻어보세요!
📢 이 글이 도움되셨나요? 공유해주세요!
여러분의 공유 한 번이 더 많은 사람들에게 도움이 됩니다 ✨
🔥 공유할 때마다 블로그 성장에 큰 힘이 됩니다! 감사합니다 🙏
💬 여러분의 소중한 의견을 들려주세요!
React Hook useEffect has a missing dependency에 대한 여러분만의 경험이나 노하우가 있으시나요?
⭐ 모든 댓글은 24시간 내에 답변드리며, 여러분의 의견이 다른 독자들에게 큰 도움이 됩니다!
🎯 건설적인 의견과 경험 공유를 환영합니다 ✨
🔔 블로그 구독하고 최신 글을 받아보세요!
🌟 React 에러부터 다양한 실생활 정보까지!
매일 새로운 유용한 콘텐츠를 만나보세요 ✨
📧 RSS 구독 | 🔖 북마크 추가 | 📱 모바일 앱 알림 설정
지금 구독하고 놓치는 정보 없이 업데이트 받아보세요!