React Hook useEffect has a missing dependency 완벽 해결법
React 개발 중 React Hook useEffect has a missing dependency 경고를 만나본 적이 있나요? 이 경고는 React 개발자라면 누구나 한 번쯤 마주치는 흔한 문제입니다. useEffect 훅을 사용할 때 ESLint의 exhaustive-deps 규칙이 의존성 배열에 누락된 변수를 감지하면 발생합니다. 이 경고를 무시하면 컴포넌트가 예상과 다르게 동작하거나 버그가 발생할 수 있습니다. 이 글에서는 React Hook useEffect has a missing dependency 에러의 원인부터 해결 방법, 그리고 예방 전략까지 완벽하게 알아보겠습니다.
🤖 AI 에러 분석 도우미
이 에러는 다음과 같은 상황에서 주로 발생합니다:
- 코드 문법 오류가 있을 때
- 라이브러리나 의존성 문제
- 환경 설정이 잘못된 경우
- 타입 불일치 문제
💡 위 해결법을 순서대로 시도해보세요. 90% 이상 해결됩니다!
에러 상세 분석
🔗 관련 에러 해결 가이드
이 경고 메시지는 React의 ESLint 플러그인이 제공하는 ‘react-hooks/exhaustive-deps’ 규칙에서 발생합니다. useEffect 내부에서 사용되는 props, state, 또는 다른 변수들이 의존성 배열에 포함되지 않았을 때 나타납니다. React는 의존성 배열의 값이 변경될 때만 effect를 재실행하는데, 필요한 의존성이 누락되면 컴포넌트가 최신 값을 참조하지 못하고 이전 값(stale closure)을 사용하게 됩니다.
예를 들어, 다음과 같은 코드에서 경고가 발생합니다:
function MyComponent({ userId }) {
const [data, setData] = useState(null);
useEffect(() => {
fetchData(userId).then(setData);
}, []); // 경고: userId가 의존성 배열에 없음
return {data};
}
이 코드는 userId가 변경되어도 effect가 재실행되지 않아 잘못된 데이터를 표시할 수 있습니다.
발생 원인 5가지
1. Props 또는 State 누락
가장 흔한 원인은 useEffect 내부에서 사용하는 props나 state를 의존성 배열에 포함하지 않는 것입니다. React는 이러한 값들이 변경될 때 effect를 재실행해야 하는지 알아야 합니다.
2. 함수 참조 문제
컴포넌트 내부에서 정의된 함수를 useEffect에서 호출할 때, 해당 함수가 의존성 배열에 없으면 경고가 발생합니다. 함수도 매 렌더링마다 새로 생성되기 때문입니다.
function MyComponent() {
const handleClick = () => {
console.log('clicked');
};
useEffect(() => {
document.addEventListener('click', handleClick);
}, []); // 경고: handleClick이 누락됨
}
3. 객체나 배열 의존성
객체나 배열을 의존성으로 사용할 때는 매 렌더링마다 새로운 참조가 생성되어 불필요한 effect 실행이 발생할 수 있습니다.
4. useCallback/useMemo 미사용
함수나 복잡한 계산 결과를 메모이제이션하지 않으면, 매번 새로운 참조가 생성되어 의존성 문제가 발생합니다.
5. 중첩된 객체 속성 사용
user.id처럼 중첩된 객체의 속성을 사용할 때, 전체 객체를 의존성에 넣으면 불필요한 재렌더링이, 속성만 넣지 않으면 경고가 발생합니다.
해결방법 7가지 (코드 포함)
방법 1: 의존성 배열에 누락된 변수 추가
가장 기본적인 해결 방법은 경고 메시지에 나온 변수를 의존성 배열에 추가하는 것입니다.
function MyComponent({ userId }) {
const [data, setData] = useState(null);
useEffect(() => {
fetchData(userId).then(setData);
}, [userId]); // userId 추가
return {data};
}
방법 2: useCallback으로 함수 메모이제이션
함수를 useCallback으로 감싸서 불필요한 재생성을 방지합니다.
function MyComponent({ userId }) {
const fetchUserData = useCallback(() => {
return fetchData(userId);
}, [userId]);
useEffect(() => {
fetchUserData().then(setData);
}, [fetchUserData]);
}
방법 3: 함수를 useEffect 내부로 이동
함수가 useEffect 내부에서만 사용된다면, 함수를 effect 안으로 이동시켜 의존성 문제를 해결할 수 있습니다.
function MyComponent({ userId }) {
useEffect(() => {
const fetchUserData = async () => {
const result = await fetchData(userId);
setData(result);
};
fetchUserData();
}, [userId]); // fetchUserData는 의존성에 불필요
}
방법 4: 함수형 업데이트 사용
setState의 함수형 업데이트를 사용하면 현재 state를 의존성에서 제거할 수 있습니다.
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setCount(prev => prev + 1); // count를 의존성에 넣지 않아도 됨
}, 1000);
return () => clearInterval(timer);
}, []); // 빈 배열로 유지 가능
}
방법 5: useRef로 최신 값 유지
useRef를 사용하면 의존성 배열을 변경하지 않고도 최신 값을 참조할 수 있습니다.
function MyComponent({ onUpdate }) {
const onUpdateRef = useRef(onUpdate);
useEffect(() => {
onUpdateRef.current = onUpdate;
});
useEffect(() => {
const interval = setInterval(() => {
onUpdateRef.current(); // 최신 함수 호출
}, 1000);
return () => clearInterval(interval);
}, []); // onUpdate를 의존성에 넣지 않아도 됨
}
방법 6: 특정 속성만 의존성에 추가
객체 전체가 아닌 필요한 속성만 의존성에 추가합니다.
function UserProfile({ user }) {
const userId = user.id;
useEffect(() => {
fetchUserDetails(userId);
}, [userId]); // user 전체가 아닌 userId만
}
방법 7: ESLint 규칙 비활성화 (최후의 수단)
정말 필요한 경우에만 특정 라인에서 ESLint 경고를 비활성화합니다. 하지만 이는 권장되지 않습니다.
useEffect(() => {
// 특별한 이유로 의존성을 추가하지 않는 경우
doSomething();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
예방법과 베스트 프랙티스
1. ESLint 규칙 준수: react-hooks/exhaustive-deps 규칙을 활성화하고 경고를 무시하지 마세요. 이 규칙은 버그를 예방하는 데 매우 중요합니다.
2. 함수 메모이제이션: useCallback과 useMemo를 적절히 활용하여 불필요한 재생성을 방지하세요.
3. Effect 분리: 하나의 useEffect에 너무 많은 로직을 넣지 말고, 관련된 로직끼리 분리하세요. 이렇게 하면 의존성 관리가 쉬워집니다.
4. 함수형 업데이트 활용: setState를 사용할 때는 가능한 한 함수형 업데이트를 사용하여 의존성을 줄이세요.
5. TypeScript 사용: TypeScript를 사용하면 타입 체크를 통해 의존성 문제를 더 쉽게 발견할 수 있습니다.
마무리
React Hook useEffect has a missing dependency 경고는 React 애플리케이션의 안정성을 위해 반드시 해결해야 하는 문제입니다. 이 글에서 소개한 7가지 해결 방법을 상황에 맞게 적용하면 대부분의 의존성 문제를 해결할 수 있습니다. 가장 중요한 것은 ESLint 경고를 무시하지 않고 근본적인 원인을 이해하여 올바른 방법으로 해결하는 것입니다. 처음에는 번거롭게 느껴질 수 있지만, 올바른 의존성 관리는 장기적으로 유지보수가 쉽고 버그가 적은 코드를 만드는 데 필수적입니다.
📚 함께 읽으면 좋은 글
Cannot read properties of undefined (reading ‘map’) 완벽 해결법 – 원인부터 예방까지
📅 2025. 10. 16.
🎯 Cannot read properties of undefined (reading ‘map’)
Cannot update a component while rendering 완벽 해결법 – 원인부터 예방까지
📅 2025. 10. 15.
🎯 Cannot update a component while rendering
Maximum update depth exceeded 완벽 해결법 – 원인부터 예방까지
📅 2025. 10. 15.
🎯 Maximum update depth exceeded
Warning: Each child in a list should have a unique “key” prop 완벽 해결법 – 원인부터 예방까지
📅 2025. 10. 11.
🎯 Warning: Each child in a list should have a unique “key” prop
Cannot update a component while rendering 완벽 해결법 – 원인부터 예방까지
📅 2025. 10. 7.
🎯 Cannot update a component while rendering
💡 위 글들을 통해 더 깊이 있는 정보를 얻어보세요!
📢 이 글이 도움되셨나요? 공유해주세요!
여러분의 공유 한 번이 더 많은 사람들에게 도움이 됩니다 ✨
🔥 공유할 때마다 블로그 성장에 큰 힘이 됩니다! 감사합니다 🙏
💬 여러분의 소중한 의견을 들려주세요!
여러분은 React Hook useEffect has a missing dependency에 대해 어떻게 생각하시나요?
⭐ 모든 댓글은 24시간 내에 답변드리며, 여러분의 의견이 다른 독자들에게 큰 도움이 됩니다!
🎯 건설적인 의견과 경험 공유를 환영합니다 ✨
🔔 블로그 구독하고 최신 글을 받아보세요!
🌟 React 에러부터 다양한 실생활 정보까지!
매일 새로운 유용한 콘텐츠를 만나보세요 ✨
📧 RSS 구독 | 🔖 북마크 추가 | 📱 모바일 앱 알림 설정
지금 구독하고 놓치는 정보 없이 업데이트 받아보세요!