2026. 7. 16.

React Maximum update depth exceeded, 반복 렌더링을 끊는 확인 순서

React Maximum update depth exceeded 오류에서 렌더 중 상태 변경과 useEffect 의존성 순환을 구분해 반복 렌더링을 멈추는 점검 순서다.

4 min read
React Maximum update depth exceeded, 반복 렌더링을 끊는 확인 순서 대표 이미지

브라우저 콘솔에 Maximum update depth exceeded가 계속 찍히고 화면이 멈춘다면, React가 느린 것이 아니라 상태 변경이 다시 같은 상태 변경을 부르는 경로가 생긴 것이다. 의존성 배열부터 비우지 말고 오류 직전에 바뀐 컴포넌트에서 setState, setCount, setData 같은 setter가 어디서 호출되는지 찾는다.

확인 순서는 세 갈래다. 컴포넌트 본문에서 바로 호출되는지, onClick={save()}처럼 렌더 순간 실행되는지, useEffect 안에서 바꾼 상태가 다시 Effect를 깨우는지 본다. 첫 목표는 setter를 지우는 것이 아니라 반복을 시작한 호출 위치를 분류하는 것이다.

React 렌더와 상태 변경이 순환하는 경로에서 세 개의 차단 지점을 보여 주는 흐름도

오류 직전 바뀐 setter부터 찾는다

프로젝트 전체를 고치기 전에 오류가 처음 나온 컴포넌트와 그 부모만 연다. 에러 스택의 컴포넌트 이름을 보고 아래 문자열을 검색한다.

setState(
setCount(
setData(
dispatch(

setter 이름은 프로젝트마다 다르다. useState의 두 번째 값이나 상태 라이브러리의 dispatch처럼 화면을 다시 그리게 만드는 호출을 찾으면 된다. 찾은 호출마다 다음 세 칸 중 하나를 붙인다.

호출 위치먼저 의심할 형태옮길 곳 또는 확인할 것
컴포넌트 함수 본문조건 없이 setter 호출계산으로 바꾸거나 이벤트로 이동
JSX 이벤트 proponClick={save()}onClick={save} 또는 콜백 함수
useEffect 내부상태 갱신 뒤 의존성도 변화Effect 필요 여부와 의존성 순환

AI에게는 "파일 전체를 다시 써 줘" 대신 아래처럼 범위를 묶어 요청한다.

이 컴포넌트에서 렌더 중 실행되는 상태 변경만 찾아라.
각 호출을 컴포넌트 본문, JSX 이벤트 prop, useEffect로 분류하고
Maximum update depth exceeded를 시작하는 한 경로만 최소 수정하라.
수정 뒤 클릭과 입력 동작을 확인할 로그도 남겨라.

렌더 중 실행된 상태 변경을 이벤트로 옮긴다

가장 빨리 찾을 수 있는 원인은 함수 호출 괄호다. 아래 코드는 버튼을 누를 때가 아니라 JSX를 계산하는 동안 save()를 실행한다.

// 잘못된 예: 렌더할 때 save가 실행된다.
<button onClick={save()}>저장</button>

// 수정: 클릭할 때 함수가 실행된다.
<button onClick={save}>저장</button>

인자를 넘겨야 한다면 함수를 즉시 실행하지 않는 콜백으로 감싼다.

<button onClick={() => save(item.id)}>저장</button>

React 커스텀 Button의 prop 전달을 확인하는 글처럼 기본 버튼은 되는데 래퍼 컴포넌트만 실패한다면, 부모의 onClick을 자식 <button>까지 전달했는지도 함께 본다.

컴포넌트 본문에 조건 없는 setter가 있어도 같은 문제가 생긴다.

function Counter() {
  const [count, setCount] = useState(0);
  setCount(count + 1);
  return <p>{count}</p>;
}

React는 상태가 바뀌면 다시 렌더한다. 다시 들어온 본문이 또 setCount를 호출하므로 멈출 지점이 없다. Keeping Components Pure - React는 렌더를 계산으로 유지하고, 사용자 행동으로 생기는 부수 효과는 보통 이벤트 핸들러에 두도록 안내한다. 화면에 보여 줄 값이 기존 props나 state로 계산 가능하다면 별도 상태로 복사하지 않고 렌더 중 계산한다.

Effect는 상태 갱신과 의존성을 함께 본다

렌더 본문과 이벤트 prop에 즉시 실행이 없다면 useEffect를 본다. useEffect - React는 Effect 무한 사이클에 두 조건이 함께 있다고 설명한다. Effect가 상태를 바꾸고, 그 상태 변경으로 다시 렌더된 뒤 Effect의 의존성이 달라져야 한다.

useEffect(() => {
  setCount(count + 1);
}, [count]);

이 코드는 count를 읽어 바꾸고, 바뀐 count가 다시 Effect를 실행한다. 빈 배열로 숨기기 전에 이 상태가 외부 시스템과 동기화되어야 하는지 묻는다. You Might Not Need an Effect - React는 렌더용 데이터를 기존 값에서 계산하거나 특정 사용자 이벤트를 처리하는 일이라면 Effect가 필요하지 않을 수 있다고 설명한다.

// 불필요한 파생 상태
useEffect(() => {
  setFullName(`${firstName} ${lastName}`);
}, [firstName, lastName]);

// 렌더 중 계산
const fullName = `${firstName} ${lastName}`;

외부 연결이나 구독처럼 Effect가 필요하다면 의존성의 참조를 확인한다. 객체와 함수는 내용이 같아 보여도 렌더마다 새로 만들면 다른 값으로 비교될 수 있다.

const options = { roomId };

useEffect(() => {
  connect(options);
}, [options]);

Removing Effect Dependencies - React는 의존성 린터를 끄기보다 객체나 함수 의존성을 피하고 실제로 반응해야 하는 원시값을 드러내도록 권한다.

useEffect(() => {
  const options = { roomId };
  connect(options);
}, [roomId]);

오류가 Effect 안에서만 반복된다면 상태 업데이트와 의존성을 함께 보는 useEffect 점검법의 로그 대조 단계가 맞다. 현재 오류의 시작 위치를 먼저 가른 뒤 Effect 안에서 달라지는 값 하나를 좁힌다.

오류가 사라진 뒤 정상 동작을 다시 확인한다

오류 메시지만 사라졌다고 끝내면 안 된다. 의존성을 삭제하거나 상태 갱신을 막아 기능까지 멈췄을 수 있다. 수정 전 재현 행동을 한 번만 실행하고 아래 결과를 확인한다.

React 반복 렌더링 수정 후 렌더 본문과 이벤트와 Effect와 콘솔을 확인하는 체크리스트
  • 첫 화면이 열릴 때 콘솔 오류가 계속 증가하지 않는다.
  • 버튼을 한 번 누르면 저장이나 상태 변경도 한 번만 일어난다.
  • 입력값이나 서버 응답처럼 실제 의존성이 바뀌면 필요한 Effect는 다시 실행된다.
  • ESLint의 Hook 의존성 경고를 주석으로 숨기지 않았다.
  • 새로고침 뒤에도 같은 사용자 행동으로 결과를 재현할 수 있다.

렌더 횟수를 코드로 확인해야 한다면 Profiler - ReactonRender 콜백을 개발 환경에서 사용할 수 있다. 다만 Profiler를 붙이기 전에 콘솔 오류와 네트워크 요청이 계속 늘어나는지부터 보는 편이 빠르다.

function onRender(id, phase) {
  console.log({ id, phase });
}

<Profiler id="ProblemArea" onRender={onRender}>
  <ProblemArea />
</Profiler>

최소 수정 뒤에도 반복이 남으면 해당 컴포넌트의 props와 상태 초기값만 남긴 작은 재현 파일을 만든다. 라이브러리 이름, React 버전, 첫 오류 스택을 함께 적어 AI나 동료에게 넘기면 원인을 다시 넓히지 않고 확인할 수 있다.

지금 할 일은 오류 스택의 첫 컴포넌트에서 setter 호출을 찾아 세 갈래로 표시하는 것이다. 렌더 본문과 이벤트 prop이 깨끗한 뒤에만 Effect의 상태와 의존성 순환을 고친다.

이 글은 AI 코딩과 개발 학습의 일반 정보 제공 목적입니다. 도구, 모델, 커리큘럼, 요금은 버전과 시점에 따라 달라질 수 있으므로 실습이나 도입 전 공식 문서와 최신 릴리스 노트를 확인하세요.

참고 출처

다음으로 읽을 기사

같은 흐름으로 이어 읽기 좋은 기사만 추려 보여줍니다.

댓글 0

이 글을 읽은 독자들의 생각을 나눠보세요.

비밀번호(선택)

첫 번째 댓글을 남겨보세요

여러분의 생각이 다른 독자에게 도움이 됩니다.