【React Native入門】3-3 UIコンポーネント FlatListとSectionList

「React Native入門　掌田 津耶乃著」にて動作確認したコードを逐一まとめた記事です。
基本は自分用のメモですので、動作確認したい場合ご利用ください。
ある程度は1記事を更新していき、セッションが切り替わったら別記事に残していこうと思います。

目次
[ P.117〜P.119 ] FlatList
[ P.120〜P.122 ] より複雑な表示を作る
[ P.122〜P.127 ] SectionListについて

---

[ P.117〜P.119 ] FlatList

```js
変数 = [
    { キー: '値' },
];

<FlatList
 data={ 変数 }
 renderItem={ this.表示 }
/>

表示 = ({ item }) => 
<Text style={ styles.スタイル名 }>{ item.キー }</Text>;
// ここの({ item })は固定っぽい
```

```js:App.js
import React, { Component } from 'react';
import { StyleSheet, Alert, Button, TextInput, Image, Switch, Slider, Picker, FlatList, StatusBar, Text, View } from 'react-native';

export default class App extends Component {
  items = [
    { key: 'Windows' },
    { key: 'MacOS' },
    { key: 'Linux' },
    { key: 'ChromeOS' },
    { key: 'Fucsia' },
  ];

  constructor(props) {
    super(props);
    this.title = 'FlatList Layout';
    StatusBar.setBackgroundColor('dark-content', true);
    StatusBar.setBackgroundColor('#008080', true);
  }

  render() {
    return (
      <View style={styles.base}>
        <View style={styles.body}>
          <Text style={ styles.title }>{ this.title }</Text>
          <FlatList
            data={ this.items }
            renderItem={ this.getItem }
          />
        </View>
      </View>
    );
  }

  getItem = ({ item }) => 
  <Text style={ styles.item }>{ item.key }</Text>;

}

const styles = StyleSheet.create ({
  base: {
    padding: 0,
    flex: 1,
  },
  body: {
    padding: 10,
    flex: 1,
  },
  title: {
    padding: 35,
    color: 'skyblue',
    textAlign: 'center',
    fontSize: 25,
  },
  item: {
    padding: 5,
    color: '#000',
    fontSize: 15,
  },
});
```

---

[ P.120〜P.122 ] より複雑な表示を作る

```js:App.js
import React, { Component } from 'react';
import { StyleSheet, Alert, Button, TextInput, Image, Switch, Slider, Picker, FlatList, StatusBar, Text, View } from 'react-native';

export default class App extends Component {
  items = [
    { name: 'Taro', age: 36, mail: 'taro@example.com' },
    { name: 'Hanako', age: 29, mail: 'hanako@example.com' },
  ];

  constructor(props) {
    super(props);
    this.title = 'FlatList Layout';
    StatusBar.setBackgroundColor('dark-content', true);
    StatusBar.setBackgroundColor('#008080', true);
    this.state = {
      message: 'Select Me!',
    }
  }

  render() {
    return (
      <View style={styles.base}>
        <View style={styles.body}>
          <Text style={ styles.title }>{ this.title }</Text>
          <Text style={ styles.message }>{ this.state.message }</Text>
          <FlatList
            data={ this.items }
            renderItem={ this.getItem }
          />
        </View>
      </View>
    );
  }

  getItem = ({ item }) => {
    return (
      <View style={ styles.item }>
        <Text
          style={ styles.itemTitle }
          onPress={ () => this.doAction(item) }
        >
          { item.name } ({ item.age })
        </Text>
        <Text style={ styles.itemMail }>
          { item.mail }
        </Text>
      </View>
    );
  }

  doAction = (item) => {
    this.setState({
      selected: item.id * 1,
      message: 'select: ' + item.name.toString()
      + '(' + item.age.toString() + ')',
    });
  }

}

const styles = StyleSheet.create ({
  base: {
    padding: 0,
    flex: 1,
  },
  body: {
    padding: 10,
    flex: 1,
  },
  title: {
    padding: 35,
    color: 'skyblue',
    textAlign: 'center',
    fontSize: 25,
  },
  item: {
    margin: 2,
    padding: 15,
    color: '#ccccff',
  },
  itemTitle: {
    padding: 10,
    borderStyle: 'solid',
    borderWidth: 1,
    backgroundColor: 'white',
    fontSize: 24,
  },
  itemMail: {
    textAlign: 'right',
    padding: 10,
    fontSize: 18,
    backgroundColor: '#000066',
    color: 'white',
  }
});
```

---

[ P.122〜P.127 ] SectionListについて

```js
<SectionList
　sections=表示用データ
　renderItem=アイテム表示
　renderSectionHeader=セクションヘッダー表示
　keyExtractor=キーの指定
/>
```

```js:App.js
import React, { Component } from 'react';
import { StyleSheet, Alert, Button, TextInput, Image, Switch, Slider, Picker, FlatList, SectionList, StatusBar, Text, View } from 'react-native';

export default class App extends Component {
  sections = [
    { title: 'PC', data: ['Windows', 'MacOS', 'ChromeOS'] },
    { title: 'Mobile', data: ['Andoroid', 'iOS'] },
  ];

  constructor(props) {
    super(props);
    this.title = 'SectionList Layout';
    StatusBar.setBackgroundColor('dark-content', true);
    StatusBar.setBackgroundColor('#008080', true);
    this.state = {
      message: 'Select Me!',
    }
  }

  render() {
    return (
      <View style={styles.base}>
        <View style={styles.body}>
          <Text style={ styles.title }>{ this.title }</Text>
          <Text style={ styles.message }>{ this.state.message }</Text>
          <SectionList
            sections={ this.sections }
            renderItem={ this.getItem }
            renderSectionHeader={ this.getSection }
            keyExtractor={ (item, index) => index }
          />
        </View>
      </View>
    );
  }

  // getItem
  getItem = ({ item }) => {
    return (
      <View style={ styles.item }>
        <Text
          style={ styles.item }
          onPress={ () => this.doAction(item) }
        >
          { item }
        </Text>
      </View>
    );
  }
  // doAction処理
  doAction = (item) => {
    this.setState({
      message: 'select:"' + item + '" item.',
    });
  }

  // getSection
  getSection = ({ section }) => {
    return (
      <Text 
        style={ styles.section }
        onPress={ () => this.doActionSec(section) }
      >
        { section.title }
      </Text>
    );
  }
  // doActionSec処理
  doActionSec = (section) => {
    this.setState({
      message: 'select:"' + section.title + '" sec.',
    });
  }

}

const styles = StyleSheet.create ({
  base: {
    padding: 0,
    flex: 1,
  },
  body: {
    padding: 10,
    flex: 1,
  },
  title: {
    padding: 35,
    color: '#000',
    textAlign: 'center',
    fontSize: 25,
  },
  section: {
    padding: 10,
    margin: 2,
    color: 'skyblue',
    fontSize: 24, 
    fontWeight: 'bold',
  },
  item: {
    margin: 2,
    padding: 15,
    color: '#fff',
    fontSize: 20, 
    backgroundColor: 'skyblue',
  },
});
```