← 전체 글로 돌아가기

Next.js

React에서 상태 관리 문제를 해결하기

React 컴포넌트의 상태 업데이트와 렌더링 문제를 체계적으로 진단하는 방법.

React에서 대량의 데이터를 다루면 상태 업데이트가 제대로 반영되지 않거나 성능이 급격히 저하될 수 있다. 로컬에서는 작은 데이터셋으로 잘 돌지만 배포 환경에서는 다르게 보일 수 있다.

처음 보이는 증상 정리

현상을 먼저 명확하게 파악한다:

  • 화면에 데이터가 안 나타나는가?
  • 데이터는 있지만 업데이트가 반영 안 되는가?
  • 인터랙션(클릭, 입력)에 반응하지 않는가?
  • 페이지가 느리게 로드되는가?

각 상황마다 원인이 다르므로 증상을 명확히 하는 것이 중요하다.

원인을 나누는 기준

React 문제는 세 가지로 나뉜다:

  1. 렌더링 조건: 컴포넌트가 렌더링될 조건이 맞지 않음
// 문제: useEffect 의존성 배열 누락
useEffect(() => {
  fetchData();
  // 의존성 배열 없음 → 매번 렌더링될 때마다 실행
})

// 해결
useEffect(() => {
  fetchData();
}, [])  // 초기 렌더링 때만 실행
  1. 상태 업데이트: setState가 제대로 호출되지 않음
const [items, setItems] = useState([]);

// 문제: 직접 수정
items.push(newItem);  // ❌ React가 변경을 감지 못함

// 해결
setItems([...items, newItem]);  // ✓ 새 배열 객체
  1. 이벤트 흐름: 이벤트가 발생했지만 핸들러가 실행 안 됨

브라우저 개발자 도구로 확인

모바일 폭으로 변경하고 키보드 입력을 시뮬레이션한다.

npm run build

이후 브라우저 개발자 도구에서:

  1. React DevTools 확장 프로그램 설치
  2. Components 탭에서 컴포넌트 트리 확인
  3. 각 컴포넌트의 props와 state 확인
  4. 상태가 실제로 변경되는지 추적

성능 측정

대량 데이터 처리 시 성능 문제가 있는지 확인한다.

// 렌더링 시간 측정
console.time('render');
// 렌더링 코드
console.timeEnd('render');

// 또는 React Profiler 사용
import { Profiler } from 'react';

<Profiler id="expensive-component" onRender={onRender}>
  <ExpensiveComponent />
</Profiler>

특정 컴포넌트가 반복해서 렌더링되면 메모이제이션(React.memo, useMemo)을 고려한다.

단계별 확인

  1. 상태가 변경되는가?

    • console.log로 setState 호출 확인
    • React DevTools에서 상태값 변경 추적
  2. 컴포넌트가 다시 렌더링되는가?

    • 콘솔에 렌더링 로그 추가
    • 각 렌더링 사이의 시간 간격 확인
  3. DOM이 업데이트되는가?

    • 브라우저 개발자 도구 Elements 탭에서 HTML 변경 확인
    • Mutation Observer로 DOM 변경 추적

마지막 점검

문제를 해결한 후:

  • 작은 데이터셋에서 테스트
  • 중간 크기 데이터셋에서 성능 확인
  • 실제 프로덕션 데이터 크기로 테스트

각 단계에서 문제가 없는지 확인해야 배포 후 서프라이즈를 피할 수 있다.