React Nativeでアプリの画面をつくろう（サブコンポーネントを作成する）

# はじめに
ReactNativeのデモ画面から随分ファイルが大きくなってきた。
このままさらに大きくなるのかとおもったら、componentを別で作ってそれを読み込むことで
ファイルのサイズを小さいままにすることができるそうだ。
よかった、、、これで助かった。やってみよう。

# おさらい。Expoを起動する
プロンプトを起動。
アプリ（MyApp）を保管しているディレクトリ（C:\Users\watya\myApp）へ移動して、expo起動

```
cd C:\Users\watya\myApp
expo start
```

# やりたいこと
下のコードのitemContainer配下をまるっと別のファイルで管理できるようにしたい。
やってみよう。

```
export default function App() {
  return (
    <View style={styles.container}>
        <View style={styles.itemContainer}>
          <View style={styles.leftContainer}>
            <Image
              style={{ width: 100, height: 100}}
              source={{uri: 'https://1.bp.blogspot.com/-ZOg0qAG4ewU/Xub_uw6q0DI/AAAAAAABZio/MshyuVBpHUgaOKJtL47LmVkCf5Vge6MQQCNcBGAsYHQ/s1600/pose_pien_uruuru_woman.png'}} />
          </View>
          <View style={styles.rightContainer}>
            <Text style={styles.text}>
             ぴえん
            </Text>
            <Text style={styles.subText}>
             ぴえんを超えてパオン
            </Text>
          </View>
        </View>
    </View>
  );
}
```

# jsonデータ置き場を用意してjsonデータを作成する
App.jsと同じ階層にcomponentフォルダを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/c92b75d8-dbc4-a0d3-c43f-4106d3d69c6e.png)

componentフォルダの配下にListItem.jsを作成する。ここにitemContainer配下の内容を入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/2539bc43-eda1-729c-367d-5da7551fba84.png)

# App.jsからListItem.jsを呼び出す。
ListItem.jsはimportを使って宣言してやることで<ListItem>タグとして使えるようになる。

```:App.js
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, Image } from 'react-native';
import ListItem from './components/ListItem.js';

export default function App() {
  return (
    <View style={styles.container}>
      <ListItem />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
```

で、ListItem.jsはこんな感じで、さっきまでApp.jsで使っていたitemContainer配下の内容を全部書く。
ポイントとしては、
```const ListItem=()=>{…}```
って定義して、
```export default ListItem;```
って書いて宣言しているところか。書きなれないので難しいけどそこは慣れて行けばいいかなって思った。

```:ListItem.js
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, Image } from 'react-native';

const styles = StyleSheet.create({
  itemContainer: {
    height: 100,
    width: "100%",
    borderColor: "gray",
    borderWidth: 1,
    flexDirection: "row",
  },
  leftContainer: {
    backgroundColor: "red",
    width: 100
  },
  rightContainer: {
    flex:1,
  },
  text: {
    fontSize: 16,
  },
  subText: {
   fontSize:12,
   color: "red" 
  }
});

const ListItem = () => {
    return (
        <View style={styles.itemContainer}>
        <View style={styles.leftContainer}>
          <Image
            style={{ width: 100, height: 100}}
            source={{uri: 'https://1.bp.blogspot.com/-ZOg0qAG4ewU/Xub_uw6q0DI/AAAAAAABZio/MshyuVBpHUgaOKJtL47LmVkCf5Vge6MQQCNcBGAsYHQ/s1600/pose_pien_uruuru_woman.png'}} />
        </View>
        <View style={styles.rightContainer}>
          <Text style={styles.text}>
           ぴえん
          </Text>
          <Text style={styles.subText}>
           ぴえんを超えてパオ～ン
          </Text>
        </View>
      </View>
    )
}

export default ListItem;
```

結果がこちら。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/b075348d-a4d1-1ff0-a513-ca41bbf01d74.png)

# ListItemへ値を引数渡しする
だんだんプログラムっぽくなってきた。
値を渡したいときは↓↓の要領で書けばOK。

```:App.js
    <View style={styles.container}>
      <ListItem 
        imageUrl="https://1.bp.blogspot.com/-ZOg0qAG4ewU/Xub_uw6q0DI/AAAAAAABZio/MshyuVBpHUgaOKJtL47LmVkCf5Vge6MQQCNcBGAsYHQ/s1600/pose_pien_uruuru_woman.png"
        title="ぴえん"
        subtitle="ぴえんを超えて、パオ～ン"
      />
    </View>
  );
```

```:ListItem.js
const ListItem = ({ imageUrl, title, subtitle }) => {
    return (
        <View style={styles.itemContainer}>
        <View style={styles.leftContainer}>
          <Image
            style={{ width: 100, height: 100}}
            source={{uri: imageUrl}} />
        </View>
        <View style={styles.rightContainer}>
          <Text style={styles.text}>
           {title}
          </Text>
          <Text style={styles.subText}>
          {subtitle}
          </Text>
        </View>
      </View>
    )
}
```

結果がこちら。ListItem.jsで変数を使うときは{}で囲んであげるのがポイントっぽい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/6d1a1eda-4e6c-e5bd-98ba-0385bea94b59.png)

# コンポーネントの使いまわし
ListItem.jsで定義したListItemは使いまわせる。
さっき覚えた変数を活用すれば、同じコンポーネントでも違った感じに表示させることができる。

```
export default function App() {
  return (
    <View style={styles.container}>
      <ListItem 
        imageUrl="https://1.bp.blogspot.com/-2RTmt7y_Ycg/WKFi_E40G1I/AAAAAAABBrY/sbpyWevqoe4Ld9DoKC9yH_yH5BtlFTu3ACLcB/s800/face_angry_woman2.png"
        title="Lv1"
        subtitle="おこ"
      />
      <ListItem 
        imageUrl="https://4.bp.blogspot.com/-BlGyM7lx9nc/WKFi_LR_xRI/AAAAAAABBrc/N3GKs0uNnss1o70wd8m-SSnMtb-0ELAFgCLcB/s800/face_angry_woman3.png"
        title="Lv2"
        subtitle="激おこ"
      />
      <ListItem 
        imageUrl="https://4.bp.blogspot.com/-BlGyM7lx9nc/WKFi_LR_xRI/AAAAAAABBrc/N3GKs0uNnss1o70wd8m-SSnMtb-0ELAFgCLcB/s800/face_angry_woman4.png"
        title="Lv3"
        subtitle="激おこぷんぷん丸"
      />
    </View>
  );
}
```

結果がこちら。使いまわし最高だな！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/9c345eab-bce9-058d-59c1-7eec9afb66a4.png)

# 外部データから変数を読み込ませる
## jsonデータを作成する
外部データはjson形式で記述する。
新たにdummiesフォルダを作成して、その下にarticle.jsonを入れる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/94ceca7f-446d-fd32-f1b3-1da85d76ec0b.png)


```:article.json
[
    {
        "imageUrl": "https://1.bp.blogspot.com/-2RTmt7y_Ycg/WKFi_E40G1I/AAAAAAABBrY/sbpyWevqoe4Ld9DoKC9yH_yH5BtlFTu3ACLcB/s800/face_angry_woman2.png",
        "title": "Lv1",
        "subtitle": "おこ"
    },
    {
        "imageUrl": "https://4.bp.blogspot.com/-BlGyM7lx9nc/WKFi_LR_xRI/AAAAAAABBrc/N3GKs0uNnss1o70wd8m-SSnMtb-0ELAFgCLcB/s800/face_angry_woman3.png",
        "title": "Lv2",
        "subtitle": "激おこ"
    },
    {
        "imageUrl": "https://2.bp.blogspot.com/-oMkKgonQVLA/WKFi_RED_nI/AAAAAAABBrg/eIRv_ibAj7MypkA7zM8IWLI-ertdUUjtQCLcB/s800/face_angry_woman4.png",
        "title": "Lv3",
        "subtitle": "激おこぷんぷん丸"
    },
    {
        "imageUrl": "https://1.bp.blogspot.com/-wjnvPZuhLOw/WKFi_ZebVfI/AAAAAAABBrk/7v2rP39nR14kGcpkSX52W61WDe7V-y6wACLcB/s800/face_angry_woman5.png",
        "title": "Lv4",
        "subtitle": "ムカ着火ファイヤー"
    }
]
```

## jsonデータを読み込む
ファイルの読み込みはimportを使う。
jsonデータの内容を繰り返し読み込むときは、App関数の中でmap関数をつかって、constへ格納させる。
格納した変数は、<View>コンポーネントの中に書くと、Viewを要素の数だけ繰り返し表示するそうだ。これは楽だな。。。

```:App.js
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, Image } from 'react-native';
import ListItem from './components/ListItem.js';
import articles from './dummies/article.json'

export default function App() {
  const items = articles.map((article,index) => {
    return (
      <ListItem
        imageUrl={article.imageUrl}
        title={article.title}
        subtitle={article.subtitle}
        key={index}
      />
    );
  });

  return (
    <View style={styles.container}>
      {items}
    </View>
  );
}
```

結果がこちら。なるほどぉ～・・・。書き方が今までと違うからちょっと面食らうけど、覚えるとかなり短いコードで書けるなぁ、いいね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/2cb10aeb-0a28-57b0-9200-9188add662ea.png)