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 애플리케이션을 개발할 수 있습니다. 에러가 발생하면 스택 트레이스를 따라가며 어떤 컴포넌트에서 문제가 발생했는지 정확히 파악하고, 본문에서 설명한 패턴 중 적합한 해결책을 선택하세요.
📚 함께 읽으면 좋은 글
Cannot update a component while rendering 완벽 해결법 – 원인부터 예방까지
📅 2025. 10. 4.
🎯 Cannot update a component while rendering
Cannot update a component while rendering 완벽 해결법 – 원인부터 예방까지
📅 2025. 10. 1.
🎯 Cannot update a component while rendering
Cannot update a component while rendering 완벽 해결법 – 원인부터 예방까지
📅 2025. 9. 29.
🎯 Cannot update a component while rendering
Cannot update a component while rendering 에러 해결법 – 원인 분석부터 완벽 해결까지
📅 2025. 8. 30.
🎯 Cannot update a component while rendering
Cannot read properties of undefined (reading ‘map’) 완벽 해결법 – 원인부터 예방까지
📅 2025. 10. 7.
🎯 Cannot read properties of undefined (reading ‘map’)
💡 위 글들을 통해 더 깊이 있는 정보를 얻어보세요!
📢 이 글이 도움되셨나요? 공유해주세요!
여러분의 공유 한 번이 더 많은 사람들에게 도움이 됩니다 ✨
🔥 공유할 때마다 블로그 성장에 큰 힘이 됩니다! 감사합니다 🙏
💬 여러분의 소중한 의견을 들려주세요!
Cannot update a component while rendering에 대한 여러분만의 경험이나 노하우가 있으시나요?
⭐ 모든 댓글은 24시간 내에 답변드리며, 여러분의 의견이 다른 독자들에게 큰 도움이 됩니다!
🎯 건설적인 의견과 경험 공유를 환영합니다 ✨
🔔 블로그 구독하고 최신 글을 받아보세요!
🌟 React 에러부터 다양한 실생활 정보까지!
매일 새로운 유용한 콘텐츠를 만나보세요 ✨
📧 RSS 구독 | 🔖 북마크 추가 | 📱 모바일 앱 알림 설정
지금 구독하고 놓치는 정보 없이 업데이트 받아보세요!