2026. 7. 17.

React Cannot update a component 경고, 첫 사용자 코드 줄부터 추적하세요

React의 Cannot update a component while rendering a different component 경고에서 원인 setter를 찾고, 이벤트와 Effect 중 맞는 실행 시점으로 옮겨 확인하는 순서다.

3 min read
React Cannot update a component 경고, 첫 사용자 코드 줄부터 추적하세요 대표 이미지

개발 콘솔에 Cannot update a component while rendering a different component가 보이면 React 설치부터 의심할 필요는 없다. 한 컴포넌트가 JSX를 계산하는 동안 다른 컴포넌트의 상태 setter를 실행한 상황부터 찾는다.

먼저 경고 아래 호출 스택에서 node_modules가 아닌 애플리케이션 파일의 첫 줄을 연다. 그 줄의 setSomething(...)이나 부모에게서 받은 onChange(...)가 컴포넌트 본문에서 즉시 실행되는지 확인한다. 사용자 클릭 때문에 바뀌는 값이면 이벤트 핸들러로 옮기고, 외부 시스템과 맞추는 작업일 때만 Effect를 검토한다.

React 개발 콘솔 경고에서 애플리케이션 코드의 setter 호출 줄을 추적하는 비공식 코드 화면

경고 스택에서 setter 호출 줄을 연다

경고에 등장하는 두 컴포넌트 이름만 보고 부모 파일 전체를 고치면 범위가 커진다. 호출 스택을 아래로 내려가며 프로젝트의 src, app, components 아래 파일을 찾는다. 그중 가장 먼저 실행된 앱 코드 줄에 중단점을 두거나 임시 로그를 넣어 어떤 렌더에서 호출되는지 재현한다.

아래 예에서는 Child가 렌더되는 순간 부모의 setCount를 호출한다. 조건이 있어도 호출 시점은 여전히 렌더 안이다.

function Parent() {
  const [count, setCount] = useState(0);
  return <Child count={count} setCount={setCount} />;
}

function Child({ count, setCount }) {
  if (count === 0) {
    setCount(1);
  }

  return <button>현재 값 {count}</button>;
}

React는 렌더 코드를 같은 입력에서 같은 JSX를 계산하는 단계로 다룬다. React의 순수 컴포넌트 규칙은 렌더 중 부수 효과를 분리하라고 설명한다. 조건을 더 붙이는 것보다 setter를 실행시킨 사건을 찾는 것이 먼저다.

클릭 때문에 바뀐다면 이벤트에서 함께 갱신한다

버튼 클릭, 입력, 드래그처럼 사용자의 행동이 원인이라면 setter를 그 이벤트 핸들러 안으로 옮긴다. React의 set-state-in-render 규칙도 무조건적인 렌더 중 상태 설정 대신 이벤트 시점에서 값을 제한하거나 갱신하는 예를 제시한다.

function Child({ count, setCount }) {
  function handleStart() {
    setCount(current => (current === 0 ? 1 : current));
  }

  return (
    <button onClick={handleStart}>
      현재 값 {count}
    </button>
  );
}

자식의 내부 상태와 부모 알림이 같은 클릭에서 함께 일어나야 한다면 둘 다 같은 이벤트 함수에서 처리한다. Effect가 필요하지 않은 경우는 자식 상태가 바뀐 뒤 Effect로 부모를 다시 알리는 대신, 원인 이벤트에서 두 업데이트를 함께 실행하는 방식을 보여 준다.

렌더 계산에서 사용자 이벤트와 외부 시스템 동기화로 setter 실행 시점을 나누는 흐름도

AI에게 수정시킬 때도 경고 없애기만 쓰지 않는다. 호출 위치와 유지할 동작을 함께 제한한다.

Child가 렌더 중 Parent의 setCount를 호출한다.
버튼을 눌렀을 때 count가 0에서 1로 바뀌는 동작은 유지한다.
setter를 handleStart 이벤트로 옮기고, 수정 파일과 검증 절차를 먼저 제안해라.

비슷한 AI 수정 범위를 통제하려면 AI가 파일을 너무 많이 고칠 때 수정 범위를 묶는 법도 이어서 볼 수 있다.

외부 시스템 동기화만 Effect 후보로 남긴다

렌더 중 호출을 발견했다고 모두 useEffect로 감싸면 경고는 사라져도 추가 렌더나 반복 실행이 생길 수 있다. React의 useEffect 공식 문서는 Effect를 네트워크 연결, 브라우저 이벤트 구독, 제3자 위젯 같은 외부 시스템과 컴포넌트를 동기화하는 수단으로 정의한다.

판단 질문은 하나다. “이 코드는 사용자 이벤트가 아니라 React 밖의 시스템 상태와 화면을 맞추는가?” 답이 아니면 계산 가능한 값은 렌더에서 바로 계산하고, 클릭 결과는 이벤트에서 갱신한다. 답이 맞다면 Effect의 의존성과 cleanup을 함께 설계한다.

useEffect(() => {
  function handleOnline() {
    setOnline(true);
  }

  window.addEventListener('online', handleOnline);
  return () => window.removeEventListener('online', handleOnline);
}, []);

Effect를 추가한 뒤 다시 반복 실행된다면 useEffect 상태 업데이트와 의존성을 함께 보는 법에서 의존성 변화와 외부 시스템 유무를 다시 확인한다. Effect는 경고를 숨기는 보관함이 아니다.

같은 동작을 재현해 경고와 화면을 함께 확인한다

코드를 옮긴 뒤 개발 서버를 다시 띄우고 경고를 만들었던 클릭이나 입력을 같은 순서로 반복한다. 콘솔만 조용해졌는지 보지 말고 화면 결과와 자동 검사도 함께 확인한다.

React setter 수정 뒤 재현, 콘솔, 화면 동작, lint를 차례로 확인하는 체크리스트
npm run lint
npm run build
  • 경고를 만들었던 조작을 두 번 이상 반복한다.
  • Console에서 같은 경고가 다시 나타나지 않는지 본다.
  • 버튼 값, 폼 상태, 부모 화면이 이전 의도대로 바뀌는지 확인한다.
  • lint와 build에서 새 Effect 의존성 경고나 타입 오류가 생기지 않았는지 본다.

경고 필터를 끄거나 console.error를 덮어쓰는 수정은 되돌린다. 완료 기준은 메시지 은폐가 아니라 동일한 사용자 동작, 조용한 콘솔, 통과한 검사 세 가지다.

공식 문서에서 확인할 지점

오늘은 경고 스택의 첫 앱 코드 줄을 열고, setter가 렌더 본문에서 즉시 실행되는 한 곳만 이벤트나 외부 동기화 시점으로 옮긴 뒤 같은 조작을 재현하면 된다.

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

다음으로 읽을 기사

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

댓글 0

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

비밀번호(선택)

첫 번째 댓글을 남겨보세요

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