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의 렌더링 순서를 생각해야 한다:
- 컴포넌트가 마운트됨 (초기 상태는 보통 비어 있음)
- 처음 렌더링이 일어남 (이 시점에 상태가 없으면 문제 발생)
- useEffect가 실행되고 데이터를 가져옴
- 상태가 업데이트되고 다시 렌더링됨
로컬 개발에서는 캐시되거나 빠르게 로드되는 데이터 때문에 2번 단계에서 문제가 안 드러날 수 있다. 하지만 네트워크가 느린 모바일 환경에서는 3번까지 시간이 걸려서 2번 단계에서 화면이 망가진다.
로컬과 운영 비교: 환경에 따른 차이
로컬 개발 서버와 운영 서버의 응답 속도가 다르다. 로컬은 instant하지만 운영은 네트워크 지연이 있다.
로컬에서 강제로 느린 네트워크를 시뮬레이션해서 테스트해보자.
npm run build
빌드 후 브라우저 개발자 도구의 Network 탭에서 "Slow 3G" 같은 속도 제한을 설정하고, 앱의 동작을 다시 테스트해보자.
수정 전 고정할 값: 초기 상태
상태가 비었을 때 어떻게 렌더링할지 명시해야 한다:
- 로딩 상태를 보여줄 것인가 (스피너 또는 "로딩 중...")
- 기본값을 제공할 것인가 (빈 배열 또는 기본 객체)
- 조건부 렌더링을 할 것인가 (상태가 있으면 내용, 없으면 대체 UI)
예를 들어:
const [items, setItems] = useState([]); // 빈 배열로 시작
return items.length > 0 ? <List items={items} /> : <Skeleton />;
이렇게 하면 상태가 비었을 때도 안전하게 렌더링된다.
검증: 모바일에서 직접 확인
모바일 환경에서의 동작을 확인해야 한다:
npm run build후 로컬 IP로 서버를 열어서 휴대폰에서 접속- 앱 시작 시 로딩 상태가 제대로 보이는가
- 데이터가 로드된 후 내용이 제대로 나타나는가
- 스크롤할 때 레이아웃이 안정적인가
이 세 가지를 모두 확인하면, 상태 관리 문제를 대부분 해결할 수 있다.