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はモバイルデバイス向けに最適化されています:フラット化最適化中に余分なネイティブビューを作成せず、親スタイルが変更されたときにカスケード更新を正しく処理します。
Viewコンポーネントには、外観、レイアウト、インタラクティビティを制御するための豊富なプロパティセットがあります。すべてのプロパティは、スタイルプロパティ、タッチイベント、アクセシビリティ、プラットフォーム固有の機能のいくつかのカテゴリに分類されます。主要なグループを見てみましょう。
Viewはモバイルプラットフォーム向けのすべての標準CSSプロパティをサポートしています。主なものには、配置用のflexDirection、justifyContent、alignItems、間隔用のmargin、padding、外観用のbackgroundColor、borderRadius、サイズ用のwidth、height、maxHeightが含まれます。
Viewは、onStartShouldSetResponder、onMoveShouldSetResponder、onResponderGrantのプロパティを介してタッチイベントを処理できます。これらのイベントにより、ライブラリなしでカスタムジェスチャーを実装できます。標準的なタップには、onTouchStart、onTouchEnd、onPress(PressableまたはTouchableOpacityを介して)が使用されます。
iOSでは、シャドウ用にshadowColor、shadowOffset、shadowOpacity、shadowRadiusが利用できます。Androidではこれらのプロパティは無視され、代わりにelevation(カードのようなシャドウ)が使用されます。onLayoutコールバックはViewの寸法が変更されたときにトリガーされ、アダプティブレイアウトに役立ちます。
FlexboxはReact Nativeで唯一のレイアウトメカニズムです(GridやFloatが利用できるウェブとは異なります)。すべての要素の配置はViewコンポーネントのFlexboxプロパティを介して行われます。デフォルトでは、ViewのflexDirectionはcolumnに設定されており、ウェブのようにrowではなく、モバイル画面の縦方向に沿っています。
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(ブロックコンテキスト) |
| width/height | デフォルトで親の100% | コンテンツに基づくauto |
| スクロール | 非対応(ScrollViewが必要) | overflow: auto/scroll |
| シャドウ | iOS: shadow*、Android: elevation | box-shadow |
| イベント処理 | Responderシステム | DOMイベント |
| ネイティブレンダリング | UIView / android.view.View | DOM要素 |
最も重要な違いは、デフォルトでflexDirection: columnであることです。これは明示的な設定なしでは、子要素が水平ではなく垂直に配置されることを意味します。2番目の違い:Viewの幅と高さはデフォルトで親の利用可能スペース全体に広がります(CSSのwidth: 100%に類似)。
React NativeアプリケーションでのViewの使用例を2つ見てみましょう:全画面でのコンテンツの中央揃えと、レスポンシブなカードグリッドの作成です。どちらのパターンもすべてのプロジェクトで登場します。
空の状態を作成するには、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を使用する最も一般的なパターンです。
製品や記事の2列を表示するには、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アプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。