← 전체 글로 돌아가기

Next.js

React에서 상태가 비었을 때 UI가 터질 때 대처하기

React 컴포넌트에서 초기 상태가 비어 있으면, 로컬 개발과 모바일에서 다르게 작동할 수 있다.

React 앱을 개발할 때, 초기 상태가 비어 있어서 렌더링이 실패하거나 레이아웃이 무너지는 경험을 한다. 데스크톱에서는 괜찮지만 모바일 화면에서만 문제가 나타나거나, 로컬에서는 작동하지만 배포 후에는 안 되는 경우가 많다.

사용자가 보는 상황

문제의 증상을 명확히 정리해야 한다:

  • 아무것도 나타나지 않는가 (공백)
  • 에러 화면이 나타나는가
  • 레이아웃이 이상한가 (텍스트가 겹친다거나)
  • 특정 필드만 비어 있는가

로컬 개발 환경과 배포 환경에서 같은 증상이 나타나는가, 아니면 다른가? 모바일에서만 나타나는가?

개발자가 보는 신호: 에러 메시지

브라우저 개발자 도구의 콘솔을 열고 어떤 에러가 기록되는지 봐야 한다:

  • Cannot read property of undefined — 비어 있는 객체나 배열에 접근하려고 할 때
  • TypeError: items.map is not a function — 배열로 기대했지만 undefined나 null이 왔을 때
  • Warning: Each child in a list should have a unique key prop — 맵핑할 때 key가 없을 때

에러가 명확하면, 그 에러가 어디서 나오는지 코드를 추적할 수 있다.

이벤트 흐름과 렌더링 순서

React의 렌더링 순서를 생각해야 한다:

  1. 컴포넌트가 마운트됨 (초기 상태는 보통 비어 있음)
  2. 처음 렌더링이 일어남 (이 시점에 상태가 없으면 문제 발생)
  3. useEffect가 실행되고 데이터를 가져옴
  4. 상태가 업데이트되고 다시 렌더링됨

로컬 개발에서는 캐시되거나 빠르게 로드되는 데이터 때문에 2번 단계에서 문제가 안 드러날 수 있다. 하지만 네트워크가 느린 모바일 환경에서는 3번까지 시간이 걸려서 2번 단계에서 화면이 망가진다.

로컬과 운영 비교: 환경에 따른 차이

로컬 개발 서버와 운영 서버의 응답 속도가 다르다. 로컬은 instant하지만 운영은 네트워크 지연이 있다.

로컬에서 강제로 느린 네트워크를 시뮬레이션해서 테스트해보자.

npm run build

빌드 후 브라우저 개발자 도구의 Network 탭에서 "Slow 3G" 같은 속도 제한을 설정하고, 앱의 동작을 다시 테스트해보자.

수정 전 고정할 값: 초기 상태

상태가 비었을 때 어떻게 렌더링할지 명시해야 한다:

  • 로딩 상태를 보여줄 것인가 (스피너 또는 "로딩 중...")
  • 기본값을 제공할 것인가 (빈 배열 또는 기본 객체)
  • 조건부 렌더링을 할 것인가 (상태가 있으면 내용, 없으면 대체 UI)

예를 들어:

const [items, setItems] = useState([]); // 빈 배열로 시작
return items.length > 0 ? <List items={items} /> : <Skeleton />;

이렇게 하면 상태가 비었을 때도 안전하게 렌더링된다.

검증: 모바일에서 직접 확인

모바일 환경에서의 동작을 확인해야 한다:

  1. npm run build 후 로컬 IP로 서버를 열어서 휴대폰에서 접속
  2. 앱 시작 시 로딩 상태가 제대로 보이는가
  3. 데이터가 로드된 후 내용이 제대로 나타나는가
  4. 스크롤할 때 레이아웃이 안정적인가

이 세 가지를 모두 확인하면, 상태 관리 문제를 대부분 해결할 수 있다.