LoginSignup
1
0

More than 1 year has passed since last update.

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

Posted at

はじめに

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

componentフォルダの配下にListItem.jsを作成する。ここにitemContainer配下の内容を入れる
image.png

App.jsからListItem.jsを呼び出す。

ListItem.jsはimportを使って宣言してやることでタグとして使えるようになる。

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

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

コンポーネントの使いまわし

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

外部データから変数を読み込ませる

jsonデータを作成する

外部データはjson形式で記述する。
新たにdummiesフォルダを作成して、その下にarticle.jsonを入れる

image.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を要素の数だけ繰り返し表示するそうだ。これは楽だな。。。

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

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0