FlatListとは何か、React NativeのAPIと最適化

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

FlatListは、要素の仮想化により高性能リストを表示するためのReact Nativeの主要コンポーネントです。ScrollViewとは異なり、FlatListは画面に表示されている要素のみをレンダリングし、メモリとCPUを節約します。このコンポーネントは水平・垂直スクロール、プル・トゥ・リフレッシュ、無限ローディングをサポートしています。リストアーキテクチャの詳細については、Metaのドキュメントをご覧ください。

重要なポイント

  • FlatListは仮想化されたリストコンポーネントで、表示されている要素のみをレンダリングし、スクロール時にそれらを再利用します
  • パフォーマンスはウィンドウ・レンダリングによって実現されます — 画面外の要素は作成されません
  • APIにはrenderItem、keyExtractor、ItemSeparatorComponent、ListHeaderComponent、ListFooterComponentが含まれます
  • 水平リストはhorizontalフラグで設定し、スクロール方向をX軸に変更します
  • 最適化にはkeyExtractorの適切な設定、データへのuseMemo、固定サイズへのgetItemLayoutが必要です

FlatListとは?

FlatListは、大量のデータセットを高性能にレンダリングする仮想化リストを実装するReact Nativeコンポーネントです。このコンポーネントはVirtualizedListの上に構築されており、あらゆる複雑さのフラットリストを作成するための宣言型APIを提供します。

FlatListはReact Native 0.43で、廃止されたListViewの代替として導入されました。Meta(2026年)によると、FlatListはリストを扱うReact Nativeアプリケーションの85%で使用されています。このコンポーネントは連絡先、ニュースフィード、商品カタログ、チャットなど、すべての一般的なシナリオをサポートしています。

歴史とエコシステムにおける位置づけ

FlatList以前は、開発者は手動でセルの再利用を設定する必要があるListViewを使用していました。FlatListは、AndroidのRecyclerView(2014年)やiOSのUICollectionView(2012年)と同様のウィンドウ・レンダリングを実装することで、このプロセスを自動化しました。現代のプロジェクトでは、FlatListがあらゆるリストのデファクトスタンダードです。

FlatListの仮想化の仕組み

FlatListの仮想化は、コンポーネントが画面の表示領域内にある要素と、その両側の小さなバッファのみをレンダリングするメカニズムです。残りの要素はDOMに作成されず、メモリを節約しレンダリングを高速化します。

スクロール時、FlatListは既に作成されたViewセルを再利用し、そのデータを置き換えます。これにより、10,000要素のリストに対して何千ものViewが作成されるのを防ぎます。デフォルトのバッファサイズは表示領域の上下にそれぞれ10要素ですが、windowSizeで設定可能です。

パラメータデフォルト説明
windowSize21レンダリングするページ数(1ページ=画面の高さ)
initialNumToRender10最初のレンダリング時の要素数
maxToRenderPerBatch101バッチあたりの最大レンダリング要素数
removeClippedSubviewsfalse画面外のViewを階層から削除する

これらのパラメータを最適に設定することで、スクロールの滑らかさとメモリ消費のバランスを取ることができます。大きな要素を含むリストの場合は、windowSizeを5〜7に減らすことをお勧めします。

FlatListのAPIと主要なプロパティ

FlatListのAPIには、リストの表示と動作を設定するための一連のプロパティが含まれています。必須のプロパティはdata(データ配列)とrenderItem(要素レンダリング関数)の2つです。keyExtractorは各要素に一意のキーを提供することでパフォーマンスを向上させます。

js
import React from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';

const App = () => {
  const data = Array.from({ length: 100 }, (_, i) => ({
    id: i.toString(),
    title: `Item #${i + 1}`,
  }));

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => (
        <View style={styles.item}>
          <Text>{item.title}</Text>
        </View>
      )}
      keyExtractor={item => item.id}
      ItemSeparatorComponent={() => <View style={styles.separator} />}
    />
  );
};

ItemSeparatorComponentは要素間に区切りを追加し、ListHeaderComponentListFooterComponentはリストにヘッダーとフッターを追加します。これにより、追加のラッパーなしで複雑なレイアウトを作成できます。

js
const styles = StyleSheet.create({
  item: {
    padding: 16,
    backgroundColor: '#fff',
    borderBottomWidth: 1,
    borderBottomColor: '#e0e0e0',
  },
  separator: {
    height: 1,
    backgroundColor: '#ccc',
  },
});

FlatListのパフォーマンス最適化

FlatListの最適化は、数百から数千の要素を扱うアプリケーションにとって重要です。適切に設定しないと、スクロール時の遅延、過剰なメモリ消費、低スペックデバイスでのクラッシュを引き起こす可能性があります。

最初のルールは、一意で安定したIDを持つkeyExtractorを使用することです。インデックスをキーとして使用すると、セルの再利用が正しく行われず、状態に関するバグが発生します。2番目のルールは、renderItemをuseCallbackでラップし、要素コンポーネントにReact.memoを使用することです。

固定高さのためのgetItemLayout

すべての要素の高さが同じ場合、getItemLayoutを使用すると、コンポーネントを測定せずにスクロール位置を計算できます。これにより、特に特定のインデックスにスクロールする際に、大幅なパフォーマンス向上が得られます。

js
const ITEM_HEIGHT = 80;

const getItemLayout = (data, index) => ({
  length: ITEM_HEIGHT,
  offset: ITEM_HEIGHT * index,
  index,
});

<FlatList
  data={data}
  getItemLayout={getItemLayout}
  renderItem={renderItem}
/FlatList>

データに対するuseMemoは、不要な再レンダリングを防ぎます。データがAPIから取得される場合、一度変換してキャッシュします。要素コンポーネントにReact.memoを使用して、変更されていない要素のレンダリングを回避します。

水平リストとカルーセル

水平FlatListは、horizontal={true}プロパティを追加することで作成できます。リストのスクロール方向がX軸に変わり、商品カルーセル、画像ギャラリー、水平メニューに便利です。

水平モードでは、ネイティブのカルーセルのようにステップ単位のスクロールを行うために、snapToIntervalsnapToAlignmentを正しく設定することが重要です。コンポーネントは自動的に慣性と指の離しを処理し、最も近い要素で停止します。

js
<FlatList
  horizontal
  data={images}
  renderItem={renderItem}
  keyExtractor={item => item.id}
  showsHorizontalScrollIndicator={false}
  snapToInterval={CARD_WIDTH + GAP}
  snapToAlignment="start"
  decelerationRate="fast"
  pagingEnabled
  onViewableItemsChanged={onViewableItemsChanged}
/>

onViewableItemsChangedは、表示要素が変更されたときにトリガーされるコールバックです。分析、画像の遅延読み込み、表示されているカードのみの動画再生に使用されます。

プル・トゥ・リフレッシュと無限スクロール

プル・トゥ・リフレッシュは、FlatListではrefreshingプロパティとonRefreshプロパティを使用して実装され、ローディング状態と連携して動作します。リストを下に引っ張るとonRefreshが呼び出され、refreshingフラグが繰り返しの呼び出しをブロックします。

無限スクロールは、リストの終わりに近づいたときにトリガーされるコールバックonEndReachedを通じて設定します。onEndReachedThresholdは、終端から何要素手前でイベントが発火するかを決定します。通常はカーソルベースのページネーションが使用されます。

js
const ListWithPagination = () => {
  const [data, setData] = React.useState([]);
  const [page, setPage] = React.useState(1);
  const [refreshing, setRefreshing] = React.useState(false);

  const loadMore = React.useCallback(async () => {
    const newData = await fetchPage(page);
    setData(prev => [...prev, ...newData]);
    setPage(p => p + 1);
  }, [page]);

  return (
    <FlatList
      data={data}
      renderItem={renderItem}
      keyExtractor={item => item.id}
      refreshing={refreshing}
      onRefresh={loadMore}
      onEndReached={loadMore}
      onEndReachedThreshold={0.5}
    />
  );
};

重要:onEndReachedは複数回呼び出される可能性があります。前のリクエストが完了するまで繰り返しのリクエストをブロックするために、isLoadingフラグを追加してください。ローディングを示すには、ListFooterComponentでActivityIndicatorを使用します。

よくある質問

FlatListとScrollViewの違いは何ですか?

FlatListは仮想化を使用し、表示要素のみをレンダリングするため、大量のデータでもメモリを節約します。ScrollViewはすべての子要素を一度にレンダリングするため、20〜30要素の小さなリストにのみ適しています。FlatListは100要素以上のリストに最適です。

FlatListのデータ更新時のフラッシュを修正するには?

フラッシュはデータ配列への参照が変更されたときに発生します。extraDataを使用して依存関係を渡すか、renderItemをReact.memoでラップしてください。完全に制御するには、useMemoを使用してデータ参照を安定させてください。

FlatListが別のスクロールビュー内でスクロールしないのはなぜですか?

FlatListはジェスチャーの競合のため、ScrollView内でのネストを想定していません。解決策:nestedScrollEnabled(Android)を有効にしたFlatList、セクション用のSectionList、またはListHeaderComponentを介して外部スクロールをFlatListに移行してください。

FlatListの要素の出現をアニメーション化するには?

インデックスに基づいた遅延を設定して、renderItem内でAnimated APIを使用します。スクロール時にはonViewableItemsChangedを使用してアニメーションをトリガーします。react-native-reanimatedやreact-native-lottieなどのライブラリを使用すると、複雑な出現アニメーションを簡単に作成できます。

VirtualizedListとは何ですか?FlatListとの関係は?

VirtualizedListは、FlatListとSectionListが構築されるベースとなる仮想化コンポーネントです。FlatListはVirtualizedListのラッパーで、フラットリスト向けに簡略化されたAPIを提供します。VirtualizedListはより低レベルの制御を提供しますが、直接使用されることはほとんどありません。

まとめ

  • FlatListは自動仮想化とセル再利用を備えた、React Nativeの高性能リスト用主要コンポーネントです
  • 仮想化はwindowSizeとinitialNumToRenderにより表示要素のみをレンダリングし、大規模データセットでのメモリを節約します
  • 必須プロパティ:data、renderItem、keyExtractor — リストの正しい動作を保証します
  • getItemLayoutは固定高さの要素のスクロールを高速化し、動的測定を排除します
  • 水平リストとカルーセルは、horizontalとsnapToIntervalを使用してステップ単位のスクロールを設定します
  • プル・トゥ・リフレッシュとonEndReachedは、繰り返し呼び出しを防止しながら無限ローディングを実装します
  • React.memoとuseCallbackはrenderItemに必須です — これらがないと、スクロールのたびに全要素が再レンダリングされます

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

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

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

こちらもお読みください