React Hook useEffect has a missing dependency 완벽 해결법 – 원인부터 예방까지

React Hook useEffect has a missing dependency 완벽 해결 가이드

도입

React 개발 중 “React Hook useEffect has a missing dependency” 경고 메시지를 마주한 적이 있으신가요? 이 경고는 React의 ESLint 플러그인이 useEffect 훅의 의존성 배열에 필요한 값이 누락되었음을 알려주는 메시지입니다. 많은 개발자들이 이 경고를 무시하거나 잘못된 방법으로 해결하려 시도하지만, 올바른 이해 없이 처리하면 예상치 못한 버그나 성능 문제가 발생할 수 있습니다. 이 글에서는 React Hook useEffect has a missing dependency 에러의 원인부터 올바른 해결 방법, 그리고 예방법까지 완벽하게 다루어 드리겠습니다.

🤖 AI 에러 분석 도우미

이 에러는 다음과 같은 상황에서 주로 발생합니다:

  • 코드 문법 오류가 있을 때
  • 라이브러리나 의존성 문제
  • 환경 설정이 잘못된 경우
  • 타입 불일치 문제

💡 위 해결법을 순서대로 시도해보세요. 90% 이상 해결됩니다!

에러 상세 분석

이 경고는 useEffect 내부에서 사용되는 변수나 함수가 의존성 배열(dependency array)에 포함되지 않았을 때 발생합니다. React는 useEffect의 두 번째 인자로 전달되는 배열을 통해 어떤 값이 변경될 때 effect를 다시 실행할지 결정합니다. 만약 effect 내부에서 사용하는 값이 의존성 배열에 없다면, 해당 값이 변경되어도 effect가 재실행되지 않아 오래된(stale) 값을 참조하게 됩니다.

예를 들어, 아래 코드에서 count 변수를 useEffect 내부에서 사용하지만 의존성 배열에 포함하지 않으면 경고가 발생합니다:

function Counter() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    console.log(count); // count를 사용하지만
  }, []); // 의존성 배열에 count가 없음
  
  return ;
}

발생 원인 5가지

1. 상태(State) 변수 누락

가장 흔한 원인은 useEffect 내부에서 useState로 선언된 상태 변수를 사용하면서 의존성 배열에 포함하지 않는 경우입니다.

const [user, setUser] = useState(null);

useEffect(() => {
  if (user) {
    fetchUserData(user.id); // user 사용
  }
}, []); // user 누락

2. Props 누락

컴포넌트가 받은 props를 useEffect에서 사용하지만 의존성 배열에 포함하지 않은 경우입니다.

function UserProfile({ userId }) {
  useEffect(() => {
    loadProfile(userId); // userId 사용
  }, []); // userId 누락
}

3. 함수 참조 누락

컴포넌트 내부에서 정의된 함수를 useEffect에서 호출하는 경우, 해당 함수도 의존성에 포함되어야 합니다.

const handleData = () => {
  console.log(data);
};

useEffect(() => {
  handleData(); // 함수 사용
}, []); // handleData 누락

4. 객체/배열 속성 접근

객체나 배열의 특정 속성에 접근할 때도 해당 객체/배열을 의존성에 포함해야 합니다.

const config = { apiUrl: 'https://api.example.com' };

useEffect(() => {
  fetch(config.apiUrl); // config.apiUrl 사용
}, []); // config 누락

5. Context 값 누락

useContext로 가져온 값을 useEffect에서 사용하지만 의존성 배열에 포함하지 않은 경우입니다.

const theme = useContext(ThemeContext);

useEffect(() => {
  applyTheme(theme); // theme 사용
}, []); // theme 누락

해결방법 7가지 (코드 포함)

1. 의존성 배열에 누락된 값 추가 (권장)

가장 기본적이고 권장되는 방법은 사용하는 모든 값을 의존성 배열에 추가하는 것입니다.

const [count, setCount] = useState(0);

useEffect(() => {
  console.log(count);
}, [count]); // count 추가

2. useCallback으로 함수 메모이제이션

함수가 의존성으로 필요한 경우 useCallback을 사용하여 불필요한 재생성을 방지합니다.

const fetchData = useCallback(() => {
  fetch(`/api/user/${userId}`);
}, [userId]);

useEffect(() => {
  fetchData();
}, [fetchData]); // 안정된 함수 참조

3. 함수를 useEffect 내부로 이동

함수가 useEffect 내에서만 사용된다면 내부로 이동시켜 의존성 문제를 해결할 수 있습니다.

useEffect(() => {
  const handleData = () => {
    console.log(data);
  };
  
  handleData();
}, [data]); // data만 의존성에 포함

4. 함수형 업데이트 사용

setState의 함수형 업데이트를 사용하면 현재 상태를 의존성에서 제거할 수 있습니다.

useEffect(() => {
  const interval = setInterval(() => {
    setCount(prevCount => prevCount + 1); // 함수형 업데이트
  }, 1000);
  
  return () => clearInterval(interval);
}, []); // count 불필요

5. useRef로 최신 값 참조

effect를 재실행하지 않으면서 최신 값을 참조해야 할 때 useRef를 사용합니다.

const latestCallback = useRef(callback);

useEffect(() => {
  latestCallback.current = callback;
});

useEffect(() => {
  const handler = () => latestCallback.current();
  window.addEventListener('resize', handler);
  return () => window.removeEventListener('resize', handler);
}, []); // callback 변경 시 리스너 재등록 안 함

6. 필요한 값만 구조 분해하여 사용

객체 전체가 아닌 필요한 속성만 의존성에 포함합니다.

function UserProfile({ user }) {
  const userId = user.id; // 필요한 값만 추출
  
  useEffect(() => {
    fetchProfile(userId);
  }, [userId]); // user 대신 userId만 의존성에 포함
}

7. useMemo로 객체/배열 메모이제이션

객체나 배열이 의존성일 때 useMemo를 사용하여 불필요한 재생성을 방지합니다.

const options = useMemo(() => ({
  method: 'POST',
  headers: { 'Content-Type': 'application/json' }
}), []);

useEffect(() => {
  fetch('/api/data', options);
}, [options]); // 안정된 객체 참조

예방법과 베스트 프랙티스

ESLint 규칙 활성화

eslint-plugin-react-hooks를 설치하고 활성화하여 자동으로 의존성 문제를 감지하세요.

// .eslintrc.js
{
  "plugins": ["react-hooks"],
  "rules": {
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn"
  }
}

단일 책임 원칙

하나의 useEffect는 하나의 관심사만 다루도록 분리하여 의존성 관리를 단순화하세요. 여러 독립적인 작업을 하나의 useEffect에 넣지 말고 각각 분리된 useEffect로 작성하는 것이 좋습니다.

커스텀 훅 활용

복잡한 로직은 커스텀 훅으로 분리하여 의존성 관리를 캡슐화하고 재사용성을 높이세요. 이렇게 하면 각 컴포넌트의 useEffect가 더 간결해지고 관리하기 쉬워집니다.

마무리

React Hook useEffect has a missing dependency 경고는 단순한 경고가 아니라 잠재적인 버그를 방지하기 위한 중요한 신호입니다. 이 경고를 무시하거나 eslint-disable 주석으로 억제하는 대신, 근본적인 원인을 이해하고 적절한 해결 방법을 적용하는 것이 중요합니다. 위에서 소개한 7가지 해결 방법을 상황에 맞게 활용하고, ESLint 규칙을 적극 활용하여 더 안정적인 React 애플리케이션을 개발하시기 바랍니다. 올바른 의존성 관리는 예측 가능하고 버그 없는 코드의 핵심입니다.

📚 함께 읽으면 좋은 글

1

Cannot read properties of undefined (reading ‘map’) 완벽 해결법 – 원인부터 예방까지

📂 React 에러
📅 2025. 11. 16.
🎯 Cannot read properties of undefined (reading ‘map’)

2

Error: Element type is invalid 완벽 해결법 – 원인부터 예방까지

📂 React 에러
📅 2025. 11. 13.
🎯 Error: Element type is invalid

3

Cannot update a component while rendering 완벽 해결법 – 원인부터 예방까지

📂 React 에러
📅 2025. 11. 13.
🎯 Cannot update a component while rendering

4

Error: Element type is invalid 완벽 해결법 – 원인부터 예방까지

📂 React 에러
📅 2025. 11. 11.
🎯 Error: Element type is invalid

5

Warning: Each child in a list should have a unique “key” prop 완벽 해결법 – 원인부터 예방까지

📂 React 에러
📅 2025. 11. 10.
🎯 Warning: Each child in a list should have a unique “key” prop

💡 위 글들을 통해 더 깊이 있는 정보를 얻어보세요!

📢 이 글이 도움되셨나요? 공유해주세요!

여러분의 공유 한 번이 더 많은 사람들에게 도움이 됩니다 ✨

🔥 공유할 때마다 블로그 성장에 큰 힘이 됩니다! 감사합니다 🙏

💬 여러분의 소중한 의견을 들려주세요!

이 글에서 가장 도움이 된 부분은 어떤 것인가요?

💡
유용한 정보 공유

궁금한 점 질문

🤝
경험담 나누기

👍
의견 표현하기

⭐ 모든 댓글은 24시간 내에 답변드리며, 여러분의 의견이 다른 독자들에게 큰 도움이 됩니다!
🎯 건설적인 의견과 경험 공유를 환영합니다 ✨

🔔 블로그 구독하고 최신 글을 받아보세요!

📚
다양한 주제
17개 카테고리

정기 업데이트
하루 3회 발행

🎯
실용적 정보
바로 적용 가능

💡
최신 트렌드
2025년 기준

🌟 React 에러부터 다양한 실생활 정보까지!
매일 새로운 유용한 콘텐츠를 만나보세요 ✨

📧 RSS 구독 | 🔖 북마크 추가 | 📱 모바일 앱 알림 설정
지금 구독하고 놓치는 정보 없이 업데이트 받아보세요!

답글 남기기