JMDC TECH BLOG

JMDCのエンジニアブログです

React NativeでInstagramのようなGrid表示をつくったときの学び

モバイルアプリエンジニアをやっている@mrtryです! React NativeでInstagramのようなGrid表示をつくりたくなったんですが、微妙にわからないことが多かったので防備録として記事を書きました🥳

サンプル

この記事は、以下のようなGrid表示を実装したときの紹介になります

みんな大好きなExpoでサンプルも作りました🫶 このコードを書いた際の学びをアレコレ紹介します🥳

FlatListのnumColumnsを指定する

numColumnsを指定すると、1行あたりのitem数を指定できます。 サンプルコードでは 3 を指定しているので、1行あたり3 item表示されています。

reactnative.dev

ListItemを正方形にする

InstagramみたいなUIだと、写真のListItemが正方形になっています。 aspectRatio でアスペクト比を指定できるので、 aspectRatio: 1 とすると正方形にすることができます。 flex: 1, aspectRatio: 1 を指定したListItemを横並びにすれば、画面幅いっぱいの正方形がいい感じに並びます。

reactnative.dev

Spacerを作る

ListItemを flex: 1, aspectRatio: 1 を指定して横並びにすれば、概ねいい感じですが、ListItemがnumColumnsより少ない場合の見た目はこんな感じになってしまいます。

ListItemがnumColumnsより少ない場合の見た目

これをいい感じにするために「ListItemがnumColumnsより少ないとき、足りない分のListItemを追加してスペースを埋める」という対応をしました。 サンプルコードでは一目でわかるように色をつけています。

  const renderItem: FlatListProps['renderItem'] = (props) => {
    const { item, index } = props;
    const isLastItem = index === DATA.length - 1;

    return isLastItem ? (
      <>
        <Item item={item} />
        {
          // columnsの指定数に対し、item何個分データが足りないかを計算し、その分spacerとして表示
          Array.from({ length: COLUMS - (index % COLUMS) - 1 }).map(() => (
            <View style={[styles.item, { backgroundColor: 'lightgrey' }]} />
          ))
        }
      </>
    ) : (
      <Item item={item} />
    );
  };

いい感じそう🥳

というわけで、react-nativeでInstagramのようなGrid表示をつくったときの学びでした。 よくあるUIだと思うんですが、Spacerの実装例をあまり見つけられなかったので記事にしてみました。 誰かの参考になれば嬉しいです!💃🏼

JMDCでは一緒に働けるエンジニアを募集しています! カジュアルも行っているので、興味あれば下記よりエントリーいただけますと幸いです。

hrmos.co