개발자를 희망하는 초보의 자기개발 이야기

[Vercel] React Hook useEffect has a missing dependency 본문

Tools/Vercel

[Vercel] React Hook useEffect has a missing dependency

클라우드아실 2025. 4. 3. 16:58
반응형

최근 프로젝트에서 useEffect 안에 비동기 함수를 쓰는 부분이 있었는데, ESLint가 loadAnimation() 호출 밑에 경고를 띄웠다.
bird 변수를 선언하는 부분에서 birdNameMap[birdName]을 사용하고 있는데, ESLint는 birdName을 의존성 배열에 추가하라고 요구했다.

경고에서 어떤 값 때문인지도 다 알려주기 때문에 만약 놓친부분이 맞다면 의존성 배열에 추가하면 될 것이다. 하지만 나의 경우 이 useEffect는 컴포넌트가 마운트될 때 한 번만 실행되면 되기 때문에, 의도적으로 의존성 배열을 빈 배열로 두고 있었다.

대략적인 문제의 코드는 아래와 같다.

  useEffect(() => {
    const loadAnimation = async () => {
      try {
        const bird = birdNameMap[birdName] || "default";
        const animationModule = await import(
          `@/animations/${bird}_deliver.json`
        );
        setAnimationData(animationModule.default);
      } catch (error) {
        console.error("Lottie 파일 로딩 실패:", error);
        setAnimationData(null);
      }
    };

    loadAnimation();
  }, []);

birdName은 서버로부터 전달받은 전역 상태 값이다.
회원가입 시 로티 애니메이션을 실행할 때 사용되며, 이후 생성된 결과 이미지나 프로필 이미지, 홈 화면 등에서도 재활용된다.
이처럼 여러 페이지에서 공통으로 사용되기 때문에 상태를 전역에서 관리할 필요가 있었고, 이를 위해 zustand를 도입했다.

해당 경고는 코드가 동작하는데는 문제가 없지만 Vercel에서 배포시 빌드에러를 발생시켰다. 이 상황을 해결하면서 자연스럽게 ESLint 디렉티브들에 대해 알게 되었고, 언제 어떻게 써야 할지 정리해두면 좋겠다는 생각이 들었다.

1. eslint-disable-next-line

다음 한 줄만 ESLint 규칙을 무시할 수 있다.

// eslint-disable-next-line no-console
console.log("디버깅용 로그");

한 줄짜리 예외 처리에 가장 적합하고, 가독성도 괜찮다. 의도적으로 경고를 무시하고 싶을 때 유용하게 쓰인다.
뒤에 무시하고자 하는 대상을 명시하면 해당 규칙만 정확히 끌 수 있어서 더 안전하다.

아래처럼 규칙 이름 없이 eslint-disable-next-line을 썼는데, 이것만으로도 경고가 사라지고 빌드가 정상적으로 되었다.

// eslint-disable-next-line
loadAnimation();

처음엔 이게 VSCode나 Next.js의 특수한 설정 때문인가 싶었는데, 확인해보니 공식적으로도 규칙 이름을 생략하면 해당 줄의 "모든 규칙"이 비활성화된다고 한다.

ESLint 공식 문서에서도 // eslint-disable-next-line은 생략 시 해당 줄의 모든 규칙을 끄는 것으로 동작한다고 명시돼 있다.
편해서 가장 많이 활용한 것 같다.

2. eslint-disable / eslint-enable

특정 구간에서 ESLint 규칙을 꺼두고, 이후에 다시 켜는 방식.

/* eslint-disable no-alert */
alert("여기서는 허용됨");
alert("이것도 허용됨");
/* eslint-enable no-alert */
alert("여기부터 다시 에러 발생");

여러 줄에 걸쳐 같은 규칙을 반복해서 무시해야 할 때 유용하다.
주의할 점은 enable을 빼먹으면 나도 모르게 규칙이 계속 꺼진 상태가 될 수 있다는 것.

3. 그냥 eslint-disable만 썼을 때

/* eslint-disable no-console */
console.log("이후 모든 로그 허용");
console.log("계속 허용됨");

이 경우는 파일 끝까지 규칙이 비활성화된 상태로 유지된다.
이런 방식은 가급적 피하고, 꼭 써야 한다면 범위가 명확하게 보이도록 enable을 함께 사용하는 것이 좋다.

 

정리

관련된 내용을 찾아보다가 eslint-disable 은 쓰지 말아야 한다 는 블로그 글을 발견했다. 핵심 이유는 ' eslint 는 누가 강요하지도 않았고, 원래부터 있지도 않은 - 개발자들이 더 나은 코드를 구현하고자 스스로의 의지로 직접 설정한 것' 이기 때문이다. 공감하면서 뜨끔..; 나도 급하게 배포를 위해서 해당 방법을 찾아 진행했지만 ESLint 규칙을 무시하는 건 정말 불가피할 때만 써야 할 것 같다.

가능하다면 코드 구조를 바꾸거나, ESLint 설정을 조정해서 경고 없이 깔끔하게 가는 게 좋다. 어쩔 수 없이 디렉티브를 써야 할 땐, 왜 무시하는지 주석으로 이유를 남겨두는 습관이 중요하다는 것도 느꼈다.

// eslint-disable-next-line react-hooks/exhaustive-deps -- 처음 한 번만 실행되도록 의도
  • eslint-disable 이후 코드에서 규칙 비활성화
  • eslint-enable 꺼졌던 규칙 다시 활성화
  • eslint-disable-next-line 다음 한 줄만 규칙 무시

 

참고자료

반응형

'Tools > Vercel' 카테고리의 다른 글

vercel 배포 최신 커밋 반영 안될 때  (0) 2024.09.24