⚡️

【Next.js】microCMS + React Hooksで無限スクロールからのコンテンツ取得を実装する

Next.js + microCMS での無限スクロールからのコンテンツ取得方法に関する情報がほとんどなかったのでメモしておきます。 実装に必要な最短コードになりますので必要に応じて改変してみてください。

index.tsx に記述

index.tsx
import React, { useState, useEffect } from "react"
import lodash from "lodash"

const Home = ({ posts }) => {
  const [postsNew, setPosts] = useState(posts)
  const [pageNumber, setPageNumber] = useState(1)

  useEffect(() => {
    getPost()

    window.addEventListener("scroll", handleScroll)

    return () => {
      window.removeEventListener("scroll", handleScroll)
    }
  }, [pageNumber])

  // 一番下に到達したらsetPageNumberでページ番号を更新
  const handleScroll = lodash.throttle(() => {
    if (
      window.innerHeight + document.documentElement.scrollTop !==
      document.documentElement.offsetHeight
    ) {
      return
    }
    setPageNumber(pageNumber + 1)
  }, 200)

  // 続きの記事を取得して配列に結合
  const getPost = async () => {
    if (pageNumber == 1) {
      return
    }

    // 続きの記事を取得
    const limit = 10
    const key = {
      headers: { "X-API-KEY": process.env.NEXT_PUBLIC_API_KEY },
    }
    const res = await fetch(
      `https://xxxxxx.microcms.io/api/v1/post?limit=${limit}&offset=${(pageNumber -
        1) *
        limit}`,
      key
    )
    const data = await res.json()
    var postsNext = postsNew.concat(data.contents)
    setPosts(postsNext)
  }

  return (
    <div>
      {postsNew.map(post => (
        <React.Fragment key={post.id}>
          <div>{post.title}</div>
        </React.Fragment>
      ))}
    </div>
  )
}

export const getStaticProps = async () => {
  const key = {
    headers: { "X-API-KEY": process.env.NEXT_PUBLIC_API_KEY },
  }

  const limit = 10
  const res = await fetch(
    `https://xxxxxx.microcms.io/api/v1/post?limit=${limit}`,
    key
  )
  const data = await res.json()

  return {
    props: {
      posts: data.contents,
    },
  }
}

export default Home

NEXT_PUBLIC_API_KEY に関しては .env ファイル内で NEXT_PUBLIC_<NAMAE>と指定したものになります。 v9.4 から使えるようになりました。

参考記事

零細CEO兼プログラマー投資家ピアニスト。老後は曾孫達の前でグランドピアノをエレガントに弾きこなしドヤって逝くのを夢みるフルータリアンな人。とっても冷え性。Next.js+microCMS, React Native+Expo, Firebase, TailwindCSS #XRP

© 2021, Ru- All rights reserved.