ScrollView — 概要、スクロールコンテナとReact Native

著者: IT Sectr 公開日: 2026-07-05 読了時間: 10 分

React NativeのScrollViewコンポーネントは、画面サイズを超えるコンテンツをスクロールできるコンテナです。FlatListとは異なり、ScrollViewはすべてのコンテンツを一度にレンダリングするため、少量のデータ、フォーム、既知の高さの画面に最適です。React Native Docs、2024によると、ScrollViewは垂直および水平スクロール、onScrollイベント、プログラムによる位置制御、ズームジェスチャをサポートしています。このコンポーネントはiOSではネイティブUIScrollView、AndroidではScrollViewとしてレンダリングされます。

重要ポイント

  • ScrollView — すべてのコンテンツを一度にレンダリングするスクロール可能なコンテナ
  • 垂直および水平スクロールをサポート
  • iOSではUIScrollView、AndroidではScrollViewとしてレンダリング
  • scrollToによるプログラムスクロール制御を提供
  • 大きなリストにはScrollViewではなくFlatListまたはSectionListを使用

React NativeのScrollViewとは

ScrollViewは、コンテンツをスクロール可能なコンテナで包むReact Nativeコンポーネントです。コンテンツが画面の境界を超える場合、ユーザーは垂直または水平にスクロールできます。ScrollViewはマウント時にすべての子要素をレンダリングします。画面に表示されるかどうかに関係ありません。

FlatListが表示されている要素のみをレンダリングする(遅延レンダリング)のとは異なり、ScrollViewは即座にすべてのネイティブビューを作成します。これにより、ScrollViewはフォーム、設定ページ、1画面の商品カードなど、子要素の数が少ない(20〜30まで)か、正確な数が事前にわからない場合に便利です。

React Native Using ScrollView、2024によると、ScrollViewはネストされたスクロール(ScrollView内のScrollViewなど)、端に達したときのバウンス効果、スクロールインジケータ、スナップ位置決め、ジェスチャ処理をサポートしています。iOSでは、ScrollViewはcontentInsetAdjustmentBehaviorを通じてSafeAreaパディングを自動的に追加します。

ScrollViewコンポーネントのプロパティとAPI

ScrollViewは、スクロール動作、外観、インタラクティビティを制御するための豊富なプロパティセットを提供します。主要なグループを見てみましょう:スクロール制御、視覚設定、イベント、プラットフォーム固有の機能。

方向とスクロール制御

horizontal — スクロール方向を垂直(デフォルト)から水平に切り替えます。scrollEnabled — 必要に応じてスクロールを無効にします。showsVerticalScrollIndicatorとshowsHorizontalScrollIndicatorはスクロールインジケータの表示を制御します。bounces(iOS)はコンテンツの端に達したときのバウンス効果を有効/無効にします。

ScrollViewイベント

メインイベントはonScrollで、スクロールのたびに発生し、nativeEventを含むオブジェクトを渡します。これにはcontentOffset(現在位置)、contentSize(コンテンツサイズ)、layoutMeasurement(表示領域のサイズ)が含まれます。onMomentumScrollEndは慣性スクロールの完了後に発生します。onScrollEndDrag — ユーザーが画面から指を離したときに発生します。これらのイベントは、無限スクロール、パララックス効果、遅延読み込みの実装に使用されます。

refによるプログラム制御

ScrollViewはrefを介したプログラム制御のためのメソッドを提供します:scrollTo({x、y、animated})は指定された座標にスクロールし、scrollToEnd({animated})はコンテンツの最後までスクロールし、flashScrollIndicators()は一時的にスクロールインジケータを表示します。

js
const scrollRef = useRef(null);

// 先頭にスクロール
scrollRef.current.scrollTo({ x: 0, y: 0, animated: true });

// 末尾にスクロール
scrollRef.current.scrollToEnd({ animated: true });

スクロールのプログラム制御は、チャット(最新メッセージへの自動スクロール)、フォーム(エラーフィールドへのスクロール)、カルーセル(プログラムによるスワイプ)でよく使用されます。

ScrollViewとFlatListの違い

ScrollViewとFlatListの選択は、React Nativeにおける重要なアーキテクチャ上の決定の1つです。両方のコンポーネントがスクロールを提供しますが、根本的に異なるレンダリング戦略を使用します。ScrollViewはすべてを一度にレンダリングし、FlatListは表示されている要素のみをレンダリングします。

特性ScrollViewFlatList
レンダリングすべての要素を一度に表示のみ + バッファ
パフォーマンス30+要素で低下どの数でも安定
コンテンツ任意のコンポーネント(フォーム、カード)配列からの均一な要素
データサイズ小〜中(最大30要素)大規模かつ無制限
水平スクロールはい(horizontalプロップ)はい(horizontal)
セクションいいえ(そのままレンダリング)セクションにはSectionList

選択ルール:ScrollView — 子要素の数がわかり、20〜30を超えない画面向け(ユーザープロフィール、設定フォーム、商品ページ)。FlatList — 多数の要素が予想されるリスト向け(ニュースフィード、商品カタログ、チャットメッセージ)。コンテンツが異種混合(ヘッダー、フォーム、カード、フッター)の場合は、ScrollViewが推奨されます。FlatListは均一な要素を想定しているためです。

水平スクロールとページネーション

ScrollViewはhorizontalプロップを通じて水平スクロールをサポートしており、カルーセル、画像ギャラリー、タブ、水平リストに最適です。pagingEnabledプロップ(iOS)またはsnapToIntervalと組み合わせると、ScrollViewはページベースのナビゲーションのコンポーネントになります。

水平カルーセル

horizontalプロパティはスクロール方向を変更します。pagingEnabled(iOS)はページベースのスクロールを有効にし、スクロールは要素の境界でのみ停止します。snapToIntervalは両方のプラットフォームでスナップステップをピクセル単位で設定します。

js
const ImageCarousel = ({ images }) => (
    <ScrollView
        horizontal
        pagingEnabled
        showsHorizontalScrollIndicator={false}
        onMomentumScrollEnd={handlePageChange}
    >
        {images.map((img, index) => (
            <Image
                key={index}
                source={{ uri: img }}
                style={{ width: SCREEN_WIDTH, height: 250 }}
            />
        ))}
    </ScrollView>
);

このカルーセルでは、pagingEnabledが自動的に各画像の境界にスクロールをスナップします。onMomentumScrollEndは現在のページインジケータを更新できます。このようなカルーセルはネイティブに動作し、慣性スクロールをサポートします。

スナップ位置決め

標準以外のスナップステップには、snapToInterval(ピクセル単位のステップサイズ)とsnapToAlignment(start、center、end)を使用します。snapToOffsetsを使用すると、スナップ用の特定の位置の配列を指定できます。これは異なるサイズのカードがある水平リストに便利です。

ScrollViewの実践例

2つの典型的なシナリオを見てみましょう:フォーム画面(垂直スクロール)と水平カテゴリリスト。両方とも最適な動作のために異なるプロップでScrollViewを使用しています。

例1:フォーム付きプロフィール画面

プロフィール編集ページには異種混合の要素が含まれています:アバター、複数の入力フィールド、スイッチ、保存ボタン。ScrollViewは各ブロックを個別にではなく、ページ全体をスクロールできます。

js
const ProfileScreen = () => (
    <ScrollView
        contentContainerStyle={styles.container}
        keyboardShouldPersistTaps="handled"
        showsVerticalScrollIndicator={false}
    >
        <AvatarPicker />
        <TextInput placeholder="Name" />
        <TextInput placeholder="Email" />
        <TextInput placeholder="About me" multiline />
        <SwitchRow label="Notifications" />
        <Button title="Save" />
    </ScrollView>
);

keyboardShouldPersistTaps: 'handled'プロップは、キーボードが開いているときにフォームとのスクロールと操作を可能にします。contentContainerStyleはすべてのコンテンツにパディングを適用します。このパターンはReact Nativeのすべてのフォーム画面で使用されます。

例2:水平カテゴリリスト

カテゴリ(チャット、フィルター、タブ)をナビゲートするために、チップ付きの水平ScrollViewが使用されます。このコンポーネントはマーケットプレイスやソーシャルメディアアプリケーションでよく見られます。

js
const CategoryChips = ({ categories, selected, onSelect }) => (
    <ScrollView
        horizontal
        showsHorizontalScrollIndicator={false}
        contentContainerStyle={styles.chipContainer}
    >
        {categories.map((cat) => (
            <Chip
                key={cat.id}
                label={cat.name}
                isSelected={selected === cat.id}
                onPress={() => onSelect(cat.id)}
            />
        ))}
    </ScrollView>
);

インジケータをオフにした水平ScrollViewは、カテゴリストリップの標準です。各チップは選択状態を持つ個別のコンポーネントです。showsHorizontalScrollIndicator: falseプロップはスクロールバーを削除し、モバイルアプリユーザーの期待に合致します。

よくある質問

FlatListの代わりにScrollViewを使うべき場合は?

ScrollViewは少量のデータ(最大20〜30要素)と異種コンテンツ(フォーム、プロフィール、設定画面)に適しています。長い均一なリスト(ニュースフィード、商品カタログ、メッセージ)にはFlatListを選択してください。

スクロール位置を追跡するには?

onScrollイベントをonScrollEndDragまたはonMomentumScrollEndとともに使用します。現在の垂直位置はnativeEvent.contentOffset.yにあります。パフォーマンスのために、ScrollEventThrottle(iOS)を使用してonScrollの呼び出し頻度を調整します。

多くの要素でScrollViewが遅くなるのはなぜ?

ScrollViewはマウント時にすべての要素をレンダリングし、それぞれにネイティブビューを作成します。50+要素があると、メモリとJSスレッドの負荷が増加し、フレームドロップが発生します。そのような場合は、遅延レンダリングのFlatListを使用してください。

iOSでバウンス効果を無効にするには?

bounces={false}を設定します。このプロップはiOSでのみ機能し、ScrollViewの端に達したときのスプリング効果を無効にします。Androidにはデフォルトでバウンス効果がないため、このプロップは無視されます。

ScrollViewで無限スクロールを実装するには?

ScrollViewはネイティブで無限スクロールをサポートしていません。ただし、onScrollを下端への近接チェック(contentOffset.y + 画面の高さ >= contentSize.height)と組み合わせ、要素をstateに追加できます。大量のデータには、onEndReached付きのFlatListを使用してください。

まとめ

  • ScrollView — マウント時にすべてのコンテンツをレンダリングするReact Nativeのスクロール可能コンテナ
  • horizontalプロップを通じて垂直および水平スクロールをサポート
  • プログラム制御:refを介したscrollTo、scrollToEnd、flashScrollIndicators
  • 大きなリストにはFlatListを使用 — ScrollViewは30+要素で遅くなる
  • pagingEnabled付き水平ScrollView — カルーセルとギャラリーの基盤
  • イベントonScroll、onMomentumScrollEnd、onScrollEndDragで位置を追跡
  • ScrollView内のフォームにはKeyboardShouldPersistTapsが必須

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください