카테고리 없음

[React] React 컴포넌트에서 무분별하게 refetch를 쓰면 안되는 이유

woojin06 2025. 8. 27. 21:17

이번 글은 사이드 이펙트로 인하여 refetch에 관한 문제를 다뤄보려고 합니다

문제

이게 pull 받고 난 후 상황인디여
refetch를 컴포넌트 본문에서 호출하다 보니, 리렌더링이 일어날 때마다 서버에 요청이 쏟아졌습니다.

 
렌더링 실행마다 무한 요청을 발생

이렇게 결과는

  • 버튼 하나만 눌러도 네트워크 탭에 수십 개의 요청이 찍히고,
  • 서버는 불필요한 트래픽으로 과부하가 걸렸습니다.
  • 화면도 계속 깜빡이면서 UX가 완전히 망가졌습니다.

왜 이런 문제가 생길까?

핵심은 React의 컴포넌트 렌더링 방식 때문입니다.

  • React 컴포넌트는 상태나 props가 바뀌면 리렌더링 됩니다.
  • 리렌더링될 때마다 함수 본문이 다시 실행됩니다.
  • 그런데 그 안에서 refetch()를 호출하면?
    → 렌더링 = 네트워크 요청 이 되게 됩니다

즉, refetch는 조건부로 실행되어야 하는 함수인데, 본문에 넣어버리면 사실상 자동 호출이 여러번 되어버립니다.


사이드 이펙트 관점에서 보기

이 문제를 더 본질적으로 설명하면, 결국 사이드 이펙트(side effect) 문제입니다.

  • React 컴포넌트는 기본적으로 **순수 함수(pure function)**처럼 동작해야 합니다.
    • 같은 props와 state가 들어오면 항상 같은 UI를 반환해야 하죠.
  • 하지만 refetch는 네트워크 요청을 발생시키는 함수 → 부수 효과에 해당합니다.
  • 이런 부수 효과를 컴포넌트 본문에 직접 넣어버리면,
    • 매 렌더링마다 네트워크 요청이 발생하고,
    • 컴포넌트의 순수성이 깨져서 예측 불가능한 동작이 이어집니다.

즉, refetch는 컴포넌트 본문이 아니라 사이드 이펙트를 관리하는 영역(useEffect, 이벤트 핸들러 등) 안에서 실행해야 안전합니다.


해결 방법: useEffect + 의존성 배열

저는 이 문제를 해결한 방법은 useEffect를 택했어요
refetch가 특정 조건이 만족될 때만 실행되도록 제어하면 문제는 간단히 해결 할 수 있습니다

 
// 예시 코드
function UserProfile({ userId }: { userId: string }) {
  const { data, refetch } = useQuery(['user', userId], () => fetchUser(userId));

  // ✅ userId가 바뀔 때만 refetch 실행
  useEffect(() => {
    if (userId) {
      refetch();
    }
  }, [userId, refetch]);

  return <div>{data?.name}</div>;
}

이렇게 하면 userId가 바뀔 때만 refetch가 실행되고, 나머지 경우에는 쓸데없는 서버 요청이 발생하지 않습니다.
덕분에 서버 부하도 줄고, UI도 안정적으로 동작했습니다.


더 나은 대안: enabled 옵션

사실 많은 경우엔 refetch조차 필요 없을 때가 많습니다.
React Query는 enabled라는 옵션을 제공하는데 해당 옵션은 enable 조건이 있을때 알아서 refetch를 해준답니당

사용 예시는

const { data } = useQuery(['user', userId], () => fetchUser(userId), {
  enabled: !!userId, // userId가 있을 때만 실행
});

이렇게 작성하면 userId가 없을 때는 요청 자체가 발생하지 않고, userId가 생기면 자동으로 fetch가 실행됩니다.
저는 이후 협업에서 이 방식을 더 권장하게 되었습니다.


정리

  • refetch는 원래 “수동으로 데이터를 다시 불러오기” 위한 도구입니다.
  • 그런데 컴포넌트 본문에 넣으면 리렌더링마다 호출되어 서버 요청이 폭발합니다.
  • 반드시 useEffect와 의존성 배열을 통해 제어하거나, 아예 enabled 옵션으로 대체하는 게 좋습니다.
  • 협업에서는 **“refetch는 반드시 조건부로만 사용한다”**라는 팀 규칙을 두는 게 안전합니다.
  • 사용하실 경우엔 꼭 함수 안에서 사용해주세용

다들 오늘 하루도 고생 많으셨고 즐거운 코딩 하십시요~