PIYO - Tech & Life -

React NativeのSectionListの覚書

ReactNative

React Nativeでリストを表示するときはFlatListを使いますが、セクションに分かれているような場合にはSectionListを使います。

0.42まではどちらもFlatListで、結構頑張らないといけなかったのですが、0.34からFlatList, SectionListの2つが導入されました。メモリ使用やパフォーマンスなど色々な面でListViewに勝るようです。

Better List Views in React Native · React Native
Many of you have started playing with some of our new List components already after our teaser announcement in the community group, but we are officially announcing them today! No more ListViews or DataSources, stale rows, ignored bugs, or excessive memory consumption - with the latest React Native March 2017 release candidate (0.43-rc.1) you can pick from the new suite of components what best fits your use-case, with great perf and feature sets out of the box:

FlatListはグループ分けのないリスト、SectionListはグループ分けのあるリストです。FlatListのデータは単にArrayであればよいですが、SectionListではデータやメタデータをオブジェクトにしたもののArrayになるのでちょっと複雑です(と言ってもListViewの頃に比べたらシンプル)

以下、一画面分の画面イメージとサンプルコード載せときます。あとで自分が困って検索する自信あるので、スニペット的に残しておきます。

import React, { Component } from 'react';
import {
  Text,
  View,
  SectionList,
  StatusBar,
} from 'react-native';

type Props = {};
export default class App extends Component<Props> {
  componentDidMount() {
    StatusBar.setHidden(true);
  }

  renderItem({ item }) {
    return (
      <View
        style={{
          height: 40,
          justifyContent: 'center',
          borderTopWidth: 1,
          borderTopColor: '#EAEAEA',
        }}
        >
        <Text>{item}</Text>
      </View>
    );
  }

  renderSectionHeader({ section }) {
    return (
      <View
        style={{
          height: 28,
          backgroundColor: '#F0F0F0',
          justifyContent: 'center',
        }}
        >
        <Text>{section.title}</Text>
      </View>
    );
  }

  render() {
    return (
      <SectionList
        style={{ flex: 1 }}
        keyExtractor={item => item}
        renderItem={this.renderItem.bind(this)}
        renderSectionHeader={this.renderSectionHeader.bind(this)}
        sections={[
          {
            title: 'グループA',
            data: ['ロシア', 'ウルグアイ', 'エジプト', 'サウジアラビア'],
          },
          {
            title: 'グループB',
            data: ['ポルトガル', 'スペイン', 'イラン', 'モロッコ'],
          },
          {
            title: 'グループC',
            data: ['フランス', 'ペルー', 'デンマーク', 'オーストラリア'],
          },
          {
            title: 'グループD',
            data: ['アルゼンチン', 'クロアチア','アイスランド', 'ナイジェリア'],
          },
          {
            title: 'グループE',
            data: ['ベルギー', 'スイス', 'コスタリカ', 'セルビア'],
          },
          {
            title: 'グループF',
            data: ['ドイツ', 'メキシコ', 'スウェーデン', '韓国'],
          },
          {
            title: 'グループG',
            data: ['ベルギー', 'イングランド', 'チュニジア', 'パナマ'],
          },
          {
            title: 'グループH',
            data: ['ポーランド', 'コロンビア', 'セネガル', '日本'],
          },
        ]}
      />
    );
  }
}

keyExtractorを忘れると警告がでます。というか大体忘れて警告が出て、なんだっけ?となる。Reactでkeyを渡す必要があるのと同じ理由でリスト内の各アイテムにkeyが必要です。そのkeyにdataの何を使うかを返す関数を渡しておけばOK。

renderItemrenderSectionHeaderでそれぞれの要素をどう描画するか指定しています。今回はサボって<View>使ってますが、コンポーネント使っても良さそう。

もうすぐワールドカップですね。