React Native의 View 컴포넌트는 사용자 인터페이스의 기본 구성 요소로, 모바일 플랫폼을 위한 HTML div 요소와 유사합니다. View는 모든 깊이의 중첩을 지원하고, Flexbox를 통해 자식 요소의 배치를 관리하며, 터치 이벤트를 처리합니다. React Native Docs, 2024에 따르면 View는 애플리케이션에서 가장 자주 사용되는 컴포넌트입니다 — 거의 모든 화면이 중첩된 View 컨테이너로 구축됩니다. 이 컴포넌트는 iOS에서 네이티브 UIView로, Android에서 android.view.View로 렌더링되어 네이티브 성능과 접근성을 보장합니다.
핵심 사항
View는 다른 컴포넌트의 컨테이너 역할을 하는 React Native의 기본 컴포넌트입니다. StyleSheet를 통한 스타일링, Flexbox를 통한 레이아웃, 터치 처리, 애니메이션 및 변환을 지원합니다. View는 네이티브 컨테이너 요소에 대한 추상화입니다: iOS에서는 UIView, Android에서는 android.view.View입니다.
React Native에서는 HTML 요소를 사용할 수 없습니다 — 대신 모든 레이아웃이 View로 구축됩니다. Text와 Image조차도 일반적으로 위치 지정을 위해 View로 감싸집니다. 컴포넌트는 비어 있을 수도 있고(단순한 컨테이너) 모든 중첩 깊이의 자식 요소를 얼마든지 포함할 수 있습니다.
View는 단일 JavaScript 코드베이스에서 두 플랫폼 모두에서의 렌더링을 지원합니다. Flexbox 속성, 마진, 배경, 그림자 및 테두리는 iOS와 Android에서 동일하게 작동합니다. 플랫폼 차이는 최소화됩니다 — 예를 들어 iOS의 그림자는 shadowColor/shadowOffset을 사용하는 반면 Android에서는 elevation을 사용합니다.
React Native Layout Docs, 2024에 따르면 View는 모바일 기기에 최적화되어 있습니다: flatten 최적화 중에 추가 네이티브 뷰를 생성하지 않으며 부모 스타일이 변경될 때 계단식 업데이트를 올바르게 처리합니다.
View 컴포넌트는 외관, 레이아웃 및 상호작용성을 제어하기 위한 풍부한 props 세트를 가지고 있습니다. 모든 props는 스타일 props, 터치 이벤트, 접근성 및 플랫폼별 기능의 여러 범주로 나뉩니다. 주요 그룹을 살펴보겠습니다.
View는 모바일 플랫폼을 위한 모든 표준 CSS 속성을 지원합니다. 주요 속성은 다음과 같습니다: 위치 지정을 위한 flexDirection, justifyContent, alignItems; 간격을 위한 margin, padding; 외관을 위한 backgroundColor, borderRadius; 크기 조정을 위한 width, height, maxHeight.
View는 onStartShouldSetResponder, onMoveShouldSetResponder 및 onResponderGrant props를 통해 터치 이벤트를 처리할 수 있습니다. 이러한 이벤트를 통해 라이브러리 없이 사용자 정의 제스처를 구현할 수 있습니다. 표준 탭의 경우 onTouchStart, onTouchEnd 및 onPress(Pressable 또는 TouchableOpacity를 통해)가 사용됩니다.
iOS에서는 그림자에 shadowColor, shadowOffset, shadowOpacity, shadowRadius를 사용할 수 있습니다. Android에서는 이러한 속성이 무시됩니다 — 대신 elevation(카드형 그림자)이 사용됩니다. onLayout 콜백은 View의 크기가 변경될 때 트리거되며 적응형 레이아웃에 유용합니다.
Flexbox는 React Native에서 유일한 레이아웃 메커니즘입니다(Grid와 Float를 사용할 수 있는 웹과 달리). 모든 요소 위치 지정은 View 컴포넌트의 Flexbox 속성을 통해 수행됩니다. 기본적으로 View의 flexDirection은 웹처럼 row가 아닌 column으로 설정되어 모바일 화면의 세로 방향과 일치합니다.
flexDirection은 주축 방향을 결정합니다: column(기본값) 또는 row. justifyContent는 주축을 따라 분포를 제어합니다(flex-start, center, space-between). alignItems — 교차축을 따라(stretch — 기본값). flex는 자식 요소의 사용 가능한 공간 비율을 지정합니다.
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const CardLayout = () => (
<View style={styles.card}>
<View style={styles.row}>
<View style={styles.avatar} />
<View style={styles.content}>
<Text style={styles.name}>John Doe</Text>
<Text style={styles.role}>Developer</Text>
</View>
</View>
</View>
);
예제는 일반적인 구조를 보여줍니다: 외부 View — 카드, 내부 row — 아바타와 텍스트 블록이 있는 행, content — 이름과 역할이 있는 열. 이 중첩된 View 구조는 모든 React Native 화면의 표준입니다.
View는 개념적으로 HTML div와 유사하지만, 웹에서 React Native로 코드를 이식할 때 이해해야 할 주요 차이점이 있습니다. 이러한 차이점은 렌더링, 스타일 및 기본 동작과 관련됩니다.
| 특성 | View (React Native) | div (HTML) |
|---|---|---|
| 기본 flexDirection | column | row (block 컨텍스트에서) |
| width/height | 기본적으로 부모의 100% | 내용에 따라 auto |
| 스크롤 | 지원되지 않음 (ScrollView 필요) | overflow: auto/scroll |
| 그림자 | iOS: shadow*, Android: elevation | box-shadow |
| 이벤트 처리 | Responder 시스템 | DOM 이벤트 |
| 네이티브 렌더링 | UIView / android.view.View | DOM 요소 |
가장 중요한 차이점은 기본적으로 flexDirection: column이라는 것입니다. 이는 명시적 구성 없이 자식 요소가 수평이 아닌 수직으로 배열된다는 것을 의미합니다. 두 번째 차이점: View의 너비와 높이는 기본적으로 부모의 사용 가능한 모든 공간을 채우도록 확장됩니다(CSS의 width: 100%와 유사).
React Native 애플리케이션에서 View를 사용하는 두 가지 실제 예제를 살펴보겠습니다: 전체 화면에서 콘텐츠 중앙 정렬 및 반응형 카드 그리드 만들기. 두 패턴 모두 모든 프로젝트에서 나타납니다.
빈 상태를 만들기 위해 flex: 1과 두 축에서 중앙 정렬이 있는 View가 사용됩니다. 이는 로딩 화면, 오류 상태 및 빈 목록에 대한 표준 패턴입니다.
const EmptyState = ({ message }) => (
<View style={styles.container}>
<Text style={styles.icon}>{icon}</Text>
<Text style={styles.message}>{message}</Text>
</View>
);
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
icon: { fontSize: 48 },
message: { fontSize: 16, color: '#666', marginTop: 16 },
});
flex: 1이 있는 View에서 justifyContent: center와 alignItems: center의 조합은 전체 화면에서 두 축의 콘텐츠를 중앙에 배치합니다. 이것이 React Native에서 View를 사용하는 가장 일반적인 패턴입니다.
제품이나 기사의 두 열을 표시하기 위해 flexDirection: row, flexWrap: wrap 및 고정 너비의 자식 View가 사용됩니다. 이 패턴은 React Native에서 CSS Grid를 대체합니다.
const ProductGrid = ({ products }) => (
<View style={styles.grid}>
{products.map((product) => (
<View key={product.id} style={styles.card}>
<Image source={{ uri: product.image }} />
<Text>{product.name}</Text>
</View>
))}
</View>
);
const styles = StyleSheet.create({
grid: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
},
card: { width: '48%', marginBottom: 16 },
});
이 예제에서 flexWrap: wrap이 있는 외부 View는 CSS Grid와 유사하게 작동합니다. 각 카드는 너비의 48%를 차지하며 열 사이에 간격을 둡니다. 이는 카탈로그 및 콘텐츠 피드의 일반적인 패턴입니다.
자주 묻는 질문
View는 기본적으로 flexDirection: column(HTML의 flex 컨테이너처럼 row가 아님)이며, 스크롤을 지원하지 않고, 너비가 기본적으로 부모의 100%로 확장되며, 그림자는 iOS에서 shadow* 속성과 Android에서 elevation을 통해 설정됩니다.
네, View는 onTouchStart, onTouchEnd 및 Responder 시스템을 통해 터치 이벤트 처리를 지원합니다. 그러나 버튼에는 TouchableOpacity, Pressable 또는 Button을 사용하는 것이 좋습니다 — 시각적 피드백을 제공하고 접근성 API를 준수합니다.
꼭 그렇지는 않습니다. React Native는 View flattening을 통해 렌더링을 최적화합니다 — 스타일과 이벤트가 없는 추가 View는 네이티브 트리에서 제거됩니다. 그러나 코드 가독성을 위해 View를 논리적 인터페이스 블록의 컨테이너로 사용하는 것이 좋습니다.
borderRadius를 너비와 높이의 절반으로 설정합니다(예: width: 50, height: 50, borderRadius: 25). 너비와 높이가 같으면 View가 원이 됩니다. 아바타의 표준 패턴입니다.
opacity를 0에서 1 사이로 설정합니다(예: opacity: 0.5). RGBA와 함께 backgroundColor를 사용할 수도 있습니다(backgroundColor: 'rgba(0,0,0,0.5)'). 차이점은 opacity는 전체 컨테이너와 그 내용에 적용되는 반면 RGBA는 배경에만 적용된다는 것입니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.