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

React Cannot update a component while rendering 에러 완벽 해결 가이드

도입 – Cannot update a component while rendering 에러란?

React 개발 중 Cannot update a component while rendering 에러를 만나면 당황스러울 수 있습니다. 이 에러는 React 16.8 이후 버전에서 주로 발생하며, 컴포넌트가 렌더링되는 동안 다른 컴포넌트의 상태를 업데이트하려고 할 때 나타납니다. 렌더링 프로세스는 순수 함수여야 하며 부수 효과(side effects)가 없어야 한다는 React의 핵심 원칙을 위반했을 때 발생하는 경고입니다. 이 에러를 방치하면 무한 루프, 예측 불가능한 UI 동작, 성능 저하 등 심각한 문제로 이어질 수 있습니다. 따라서 근본 원인을 정확히 파악하고 올바른 해결 방법을 적용하는 것이 매우 중요합니다.

🤖 AI 에러 분석 도우미

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

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

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

에러 상세 분석

이 에러의 정확한 메시지는 다음과 같습니다:

Warning: Cannot update a component (`ComponentB`) while rendering a different component (`ComponentA`). 
To locate the bad setState() call inside `ComponentA`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render

React는 렌더링 단계와 커밋 단계를 명확히 구분합니다. 렌더링 단계는 가상 DOM을 구성하는 순수한 계산 과정이어야 하며, 외부 상태 변경이나 API 호출 같은 부수 효과가 포함되어서는 안 됩니다. 반면 커밋 단계는 실제 DOM을 업데이트하고 부수 효과를 실행하는 단계입니다. 이 에러는 렌더링 단계에서 setState, dispatch 같은 상태 업데이트 함수를 직접 호출했을 때 발생합니다. React는 이를 감지하면 무한 렌더링 루프를 방지하기 위해 경고를 표시합니다. 에러 메시지는 어떤 컴포넌트(ComponentA)가 렌더링 중에 다른 컴포넌트(ComponentB)의 상태를 변경하려 했는지 명확히 알려줍니다.

발생 원인 5가지

1. 렌더링 중 직접 setState 호출

컴포넌트 함수 본문에서 조건문 없이 직접 setState를 호출하는 경우입니다. 이는 가장 흔한 실수로, 렌더링될 때마다 상태가 변경되어 무한 루프를 유발합니다.

function BadComponent() {
  const [count, setCount] = useState(0);
  setCount(count + 1); // 렌더링 중 직접 호출 - 잘못된 방법!
  return 
{count}
; }

2. 부모 컴포넌트에서 자식의 상태 변경

부모 컴포넌트가 렌더링되는 동안 자식 컴포넌트로 전달된 콜백에서 부모의 상태를 즉시 변경하는 경우입니다.

function Parent() {
  const [data, setData] = useState('');
  return  setData('new')} />; // 문제 발생!
}

function Child({ onRender }) {
  onRender(); // 렌더링 중 호출됨
  return 
Child
; }

3. useEffect 의존성 배열 누락

useEffect 내부에서 상태를 변경하는데 의존성 배열을 잘못 설정하거나 누락하여 매 렌더링마다 실행되는 경우입니다.

4. 조건부 렌더링에서의 상태 업데이트

JSX 표현식 내부에서 직접 상태 업데이트 함수를 호출하는 경우입니다.

{isLoading && setData(newData)} // JSX 내부에서 호출 - 위험!

5. 이벤트 핸들러를 즉시 실행

이벤트 핸들러를 참조로 전달하지 않고 렌더링 시점에 즉시 실행하는 경우입니다.

 // 잘못됨!
 // 올바름

해결방법 7가지

1. useEffect로 부수 효과 이동

상태 업데이트를 useEffect 내부로 이동시켜 렌더링 이후에 실행되도록 합니다.

function FixedComponent() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    setCount(prevCount => prevCount + 1);
  }, []); // 마운트 시 한 번만 실행
  
  return 
{count}
; }

2. 이벤트 핸들러 올바르게 전달

함수를 즉시 실행하지 않고 참조로 전달합니다.

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

3. useCallback으로 콜백 메모이제이션

자식 컴포넌트에 전달하는 콜백 함수를 useCallback으로 감싸 불필요한 재생성을 방지합니다.

function Parent() {
  const [data, setData] = useState('');
  
  const handleChildEvent = useCallback((newData) => {
    setData(newData);
  }, []);
  
  return ;
}

4. 파생 상태 대신 계산된 값 사용

다른 상태로부터 파생되는 값은 상태로 저장하지 않고 렌더링 시 계산합니다.

function UserProfile({ user }) {
  // 잘못된 방법
  // const [displayName, setDisplayName] = useState('');
  // setDisplayName(user.firstName + ' ' + user.lastName);
  
  // 올바른 방법
  const displayName = user.firstName + ' ' + user.lastName;
  
  return 
{displayName}
; }

5. useMemo로 복잡한 계산 최적화

복잡한 계산이 필요한 경우 useMemo를 사용해 메모이제이션합니다.

function ProductList({ products }) {
  const expensiveProducts = useMemo(() => {
    return products.filter(p => p.price > 1000);
  }, [products]);
  
  return 
{expensiveProducts.map(p =>
{p.name}
)}
; }

6. useLayoutEffect 활용

DOM 측정이 필요한 경우 useLayoutEffect를 사용합니다.

function MeasuredComponent() {
  const [height, setHeight] = useState(0);
  const ref = useRef(null);
  
  useLayoutEffect(() => {
    if (ref.current) {
      setHeight(ref.current.offsetHeight);
    }
  }, []);
  
  return 
높이: {height}px
; }

7. 상태 끌어올리기(Lifting State Up)

여러 컴포넌트가 공유하는 상태는 공통 부모로 끌어올립니다.

function App() {
  const [sharedState, setSharedState] = useState('');
  
  return (
    <>
      
      
    
  );
}

예방법과 베스트 프랙티스

1. ESLint 플러그인 활용: eslint-plugin-react-hooks를 설치하여 잘못된 Hook 사용을 자동으로 감지합니다. 이 플러그인은 의존성 배열 누락, 렌더링 중 상태 업데이트 등을 경고합니다.

2. 렌더링 순수성 유지: 컴포넌트 함수 본문은 항상 순수 함수로 작성합니다. 같은 props와 state에 대해 항상 같은 JSX를 반환해야 합니다.

3. 부수 효과 격리: API 호출, 타이머 설정, 구독 등 모든 부수 효과는 useEffect, useLayoutEffect 내부에서만 실행합니다.

4. React DevTools 활용: React Developer Tools의 Profiler를 사용해 불필요한 재렌더링을 찾아내고 최적화합니다.

5. TypeScript 도입: TypeScript를 사용하면 타입 시스템이 많은 실수를 컴파일 타임에 잡아줍니다.

마무리

Cannot update a component while rendering 에러는 React의 렌더링 원칙을 이해하면 쉽게 해결할 수 있습니다. 핵심은 렌더링 단계를 순수하게 유지하고, 모든 부수 효과를 적절한 생명주기 메서드나 Hook으로 이동시키는 것입니다. 이 글에서 소개한 7가지 해결 방법과 5가지 예방법을 프로젝트에 적용하면 더 안정적이고 예측 가능한 React 애플리케이션을 개발할 수 있습니다. 에러가 발생하면 스택 트레이스를 따라가며 어떤 컴포넌트에서 문제가 발생했는지 정확히 파악하고, 본문에서 설명한 패턴 중 적합한 해결책을 선택하세요.

📚 함께 읽으면 좋은 글

1

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

📂 React 에러
📅 2025. 10. 4.
🎯 Cannot update a component while rendering

2

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

📂 React 에러
📅 2025. 10. 1.
🎯 Cannot update a component while rendering

3

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

📂 React 에러
📅 2025. 9. 29.
🎯 Cannot update a component while rendering

4

Cannot update a component while rendering 에러 해결법 – 원인 분석부터 완벽 해결까지

📂 React 에러
📅 2025. 8. 30.
🎯 Cannot update a component while rendering

5

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

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

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

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

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

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

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

Cannot update a component while rendering에 대한 여러분만의 경험이나 노하우가 있으시나요?

💡
유용한 정보 공유

궁금한 점 질문

🤝
경험담 나누기

👍
의견 표현하기

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

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

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

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

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

💡
최신 트렌드
2025년 기준

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

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

답글 남기기