【GatsbyJS】ブログにInfiniteScrollを実装してみた

2020-08-06
hero画像

はじめに

おはようございます!こんにちは!こんばんは!
のふのふ(@rpf_nob)と申します!!都内のスタートアップでフロントエンドエンジニアとして働いています。

今回は GatsbyJS ブログにInfiniteScrollを実装してみたので解説します!!

※こちらの記事の内容は現在ブログには反映されておりません。 現在はページネーションで実装しています。

  • 前提
  • InfiniteScroll とは
  • パッケージのインストール
  • トップページに実装
  • タグページに実装
  • まとめ

前提

このブログは GatsbyJS の gatsby-starter-blog のテンプレートから作成しています。


ソースコードはこちら(参考になったという方は ⭐️ をポチッと押していただけると嬉しいです〜 🙇‍♂️)

InfiniteScroll とは

画面をスクロールしてページの一番下まで移動すると、自動的にさらにデータを読み込んでページを表示する仕組みのことです。

同じような機能としてはpagenationという選択肢もあったのですが、メリット・デメリットを考えて InfiniteScroll を採用しました。

とりあえず読者様にクリックさせたくないのと、スマホでさくさく見てもらいという理由が大きなところです。

個人的に InfiniteScroll という言葉の響きが好きなのもあります。


このあたりのメリット・デメリットについては以下の記事を参考にしました。

パッケージのインストール

今回はreact-infinite-scrollerを使って実装します。

$npm install --save react-infinite-scroller

こちらのパッケージで簡単にInfiniteScrollを実装できます。

トップページに実装

トップページに実装するので、src/pages/index.jsを修正します。

パッケージのインポート

src/pages/index.js
import InfiniteScroll from "react-infinite-scroller";

変数・ステートを宣言

まず変数・ステートを宣言します。

  • itemsPerPage→1 回で読み込みたい記事数
  • hasMoreItems→ ロードする記事がまだあるかどうか
  • records→ 現在読み込んでいる記事数
src/pages/index.js
const itemsPerPage = 6;
const [hasMoreItems, sethasMoreItems] = useState(true);
const [records, setrecords] = useState(itemsPerPage);

コンポーネントの設置

設置したい箇所に InfiniteScroll コンポーネントを実装します。

渡すパラメーターは以下の通りです。

  • loadMore→ ユーザーがさらにアイテムを要求したときのコールバック
  • hasMore→ ロードするアイテムがまだあるかどうか
  • loader→ アイテムがロードされている間にレンダリングするコンポーネント
  • useWindow→window にスクロールを追加するかどうか
src/pages/index.js
<InfiniteScroll
  loadMore={loadMore}
  hasMore={hasMoreItems}
  loader={
    <div className="loader" key={0}>
      Loading ...
    </div>
  }
  useWindow={true}
>
  {showItems(posts)}
</InfiniteScroll>

loadMore

loadMoreはユーザーがページの一番下に到達したときに実行される関数です。

この関数でスクロールを終了又は追加の処理をおこなっています。

posts.lengthが記事数なので、それ以上になったらスクロール終了、それ以下なら 1 回分の記事数を加算する処理を行います。

setTimeout を使用してちょっとだけローディング時間を設けています。

src/pages/index.js
const loadMore = () => {
  if (records >= posts.length) {
    sethasMoreItems(false);
  } else {
    setTimeout(() => {
      setrecords(records + itemsPerPage);
    }, 1000);
  }
};

hasMore

hasMoreにはhasMoreItemsをそのまま渡せば OK です。

これでロードするアイテムがあればさらに読み込みが行われます。

loader

loaderLoading…を表示するようにしています。

key={0}は親コンポーネントに一意のキー情報を渡す必要があるので、記載しています。

src/pages/index.js
  loader={
    <div className="loader" key={0}>
      Loading ...
    </div>
  }

useWindow

今回useWindowは画面全体に InfiniteScroll を実装したいので、trueにしています。

showItems

最後に InfiniteScroll で表示したコンテンツの中身を実装します。

postsに記事の中身が配列で入っているので、それを表示したい記事分だけitemsに格納して表示しているというイメージです。

src/pages/index.js
const showItems = posts => {
  let items = [];
  for (let i = 0; i < records; i++) {
    if (posts[i] !== undefined) {
      let node = posts[i].node;
      const title = node.frontmatter.title || node.fields.slug;
      items
        .push
        // ・・・省略・・・
        ();
    }
  }

  return items;
};

タグページに実装

タグページにも基本的にトップページと同じ実装をします。

まとめ

今回は GatsbyJS ブログにInfiniteScrollを実装してみたので解説しました!!

InfiniteScroll があるだけで結構良い感じになるので是非参考にしていただければと思います!!

pagenation よりおしゃれな感じがするのでいいですよね!

他にも GatsbyJS のブログカスタマイズをいろいろやっているので、以下もあわせてご覧いただければと思います。



最後まで見ていただきありがとうございます!! この記事が良かったと思ったら SHARE していただけると泣いて喜びます 🤣


©2020-2022.のふのふ🀄All Rights Reserved.