← 전체 글로 돌아가기

Next.js

React에서 상태 업데이트 제대로 디버깅하기

React의 상태 업데이트가 기대대로 안 되면 화면만 봐서는 알 수 없습니다. 로그와 상태 변화를 함께 봐야 합니다.

React에서 "클릭했는데 화면이 안 바뀐다" 하면 당황스럽다. 화면만 보면 상태가 제대로 업데이트됐는지, 렌더링됐는지 알 수 없다.

상태 변화 로깅하기

React Developer Tools 확장이 있지만, 제일 직관적인 방법은 콘솔 로그다.

const [count, setCount] = useState(0);

const handleClick = () => {
  console.log('클릭 전 count:', count);
  setCount(count + 1);
  console.log('setCount 호출 후 count:', count); // 아직 바뀌지 않음!
};

React의 상태 업데이트는 비동기다. setCount를 호출한 직후에 로그를 찍어도 이전 값을 본다. 다음 렌더링에서 새 값을 본다.

이벤트 흐름 추적하기

복잡한 상황에선 이벤트가 어디서 버려지는지 추적해야 한다.

const handleClick = () => {
  console.log('[Step 1] 클릭 감지');

  const result = validateInput();
  if (!result.valid) {
    console.log('[Step 2] 검증 실패:', result.error);
    return;
  }
  console.log('[Step 2] 검증 통과');

  setLoading(true);
  console.log('[Step 3] 로딩 상태로 변경');

  fetch('/api/data')
    .then(res => res.json())
    .then(data => {
      console.log('[Step 4] 서버 응답:', data);
      setData(data);
      console.log('[Step 5] 데이터 상태 업데이트');
    })
    .catch(err => {
      console.error('[Step 4] 서버 에러:', err);
    })
    .finally(() => {
      setLoading(false);
      console.log('[Step 5] 로딩 종료');
    });
};

어느 Step에서 막혔는지 명확히 보인다.

렌더링 추적하기

상태는 업데이트되는데 화면이 안 바뀐다면, 컴포넌트가 리렌더링되지 않았을 수 있다.

function MyComponent({ data }) {
  useEffect(() => {
    console.log('MyComponent 렌더링됨, data:', data);
  });

  return <div>{data}</div>;
}

콘솔에 로그가 안 보이면 이 컴포넌트가 리렌더링되지 않은 것이다. 부모 컴포넌트에서 상태 업데이트가 전파되지 않거나, React.memouseMemo 때문일 수 있다.

모바일에서 확인하기

PC에선 되는데 모바일에서 안 될 수 있다. 특히 터치와 마우스 이벤트 구분, 뷰포트 크기, 키보드 입력이 다르다.

  • PC: onClick → 마우스 클릭
  • 모바일: onClick → 터치 두 번, 길게 누르기 등으로도 발동
const handleTouch = (e) => {
  console.log('터치 이벤트:', e.type, e.touches.length);
};

return <button onTouchStart={handleTouch}>테스트</button>;

React DevTools로 상태 스냅샷 찍기

개발자 도구 → Components → 컴포넌트 선택 → Hooks에서 현재 상태를 볼 수 있다. 클릭 전후로 상태가 바뀌었는지 비교한다.

최종 확인: 네트워크와 상태를 함께 보기

Network 탭과 Console을 함께 열어둔다. 클릭하면:

  1. Console에서 로그가 순서대로 나오는지
  2. Network에서 요청이 가는지
  3. 응답이 오는지
  4. 응답 후 상태가 바뀌는지

모든 단계를 함께 보면 어디가 끊겼는지 명확해진다.

마지막으로, 상태 업데이트 문제는 대부분 각 단계를 제대로 추적하지 않아서다. 로그 몇 줄로 대부분 해결된다.