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

2020-08-06

はじめに

おはようございます!こんにちは!こんばんは!
麻雀と芝生大好きおじさんことのふのふ(@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のブログカスタマイズをいろいろやっているので、以下もあわせてご覧いただければと思います。



最後まで見ていただきありがとうございます!!


Written by のふのふ

東京で働く名古屋生まれの麻雀と芝生と娘と妻を愛するアラフォーエンジニアです。 フロントエンドよりのweb開発技術(React,TypeScriptなど)を中心に扱っています。 web開発やデータサイエンス周りの技術に興味があります。 個人開発でwebアプリをリリースすることを目標にしています。

©2020 のふのふ All Rights Reserved.