글과 댓글이 계속 겹쳐보일때, flex-1을 의심하자
flex-1이 아니라 사실 나를 의심하자..🌀
2025년 4월 17일
React Native 앱 배포 후 레이아웃 깨짐 현상 분석 및 해결
현상 요약
배포된 앱에서 댓글과 본문이 겹쳐 보이는 UI 레이아웃 문제가 발생했습니다.
expo go환경에서는 발생하지 않음development build및eas build환경에서 간헐적으로 발생- 특정 사용자 행동과 관련 없이 불규칙하게 발생


원인 추정 과정
고려한 가능성:
expo go와 빌드 환경의 차이- 빌드 환경에서 댓글 데이터 응답이 느려지는 현상
- FlatList 사용 방식 문제
- 댓글 입력 후 본문과 댓글 리스트를 동시에 refetch하면서 발생하는 비동기 타이밍 차이
디버깅 방법
2번과 4번을 고려했을 때, content 영역의 높이 변화가 의심되어 onLayout으로 실제 렌더링 시 높이를 추적했습니다.
확인 결과, 실제 크기(예: height: 355)가 찍힌 후 height: 0으로 변경되는 것을 발견했습니다. 높이가 0이 되는 순간 댓글이 위로 올라와 본문과 겹치는 것이었습니다.
왜 높이가 0이 될까? (feat. flex-1의 오남용)
문제의 본질은 부모 컨테이너의 높이가 명확하지 않은 상황에서 flex-1을 무분별하게 사용한 것이었습니다.
flex: 1은 가능한 공간을 전부 채우려고 시도합니다. 하지만 부모의 높이가 0이면 자신도
height: 0이 됩니다.
ChallengeContainer 내부에 flex-1이 있었고, 부모 높이가 정해지지 않은 상태에서 높이가 0이 되어버렸습니다. 댓글 Item 컴포넌트에도 flex-1을 적용해서 서로 남는 공간을 차지하려다 겹치는 문제가 발생했습니다.
본문 컴포넌트와 댓글 항목 모두에 flex-1을 준 것이 원인이었습니다.
flex 속성 이해하기
flex는 flex-grow, flex-shrink, flex-basis를 한 번에 지정하는 속성입니다.
flex-grow
- flex-basis보다 늘어날 수 있는지 결정
- 기본값: 0 (원래 크기 유지)
- 1 이상이면 나머지 여백을 해당 비율로 나눠 가짐
flex-shrink
- flex-basis보다 줄어들 수 있는지 결정
- 기본값: 1
- 0이면 고정 너비
flex-basis
- flex item의 기본 크기
- 기본값: auto
- flex-direction이 row면 너비, column이면 높이
flex: 1을 풀면 다음과 같습니다:
점유 크기를 0으로 만든 후 화면 비율에 따라 늘어나거나 줄어들 수 있다는 의미입니다.
FlatList와의 관계
FlatList는 내부 항목의 높이를 기준으로 가상화 렌더링을 수행합니다. flex-1이 적용된 항목은 높이가 부모 기준으로 동적으로 바뀌기 때문에, FlatList가 예상하지 못한 방식으로 렌더링합니다.
✅ FlatList 내부 항목에는 flex-1을 지양하고, 콘텐츠 기반 높이를 사용하는 것이 안정적입니다.
expo go 환경에서는 왜 정상 작동했는가?
expo go는 개발용 환경으로 다음과 같은 특성이 있습니다:
- FlatList virtualization이 완화됨
- 레이아웃 측정 오류 발생 시 내부적으로 보정(reflow) 수행
- 실제 배포 환경에서 발생할 오류를 감추는 경향
expo go에서는 문제가 숨겨진 채 정상 작동하는 것처럼 보였던 것입니다.
해결 방법
- 댓글 항목 및 본문에 사용된 flex-1 속성 제거
- 레이아웃에 의존하는 컴포넌트는 부모 높이를 명확히 지정하거나 flex-1 사용 자제
마무리
React Native 첫 개발에서 flex-1을 이해하지 않고 사용한 것이 문제였습니다. 이번 경험을 통해 개발/빌드 환경의 차이점, flex: 1의 동작 원리, FlatList의 렌더링 방식을 더 깊이 이해하게 되었습니다.
🌀 급할수록 돌아가자 🌀