フリーランス 技術調査ブログ

フリーランス/エンジニア Ruby Python Nodejs Vuejs React Dockerなどの調査技術調査の備忘録

nextjsでgetStaticPropsとDynamic routesを使ってみる

サンプル

nuxtjsで覚えておく

getStaticProps

Dynamic routes

libフォルダ

  • posts.jsファイルを作成する。APIを実行してブログデータを取得する関数を用意する
import fetch from "node-fetch"
const apiUrl = "http://jsonplaceholder.typicode.com/posts"

export async function getAllPostsData() {
    const res = await fetch(new URL(apiUrl))
    const posts = await res.json()
    return posts
}

export async function getAllPostIds() {
    const res = await fetch(new URL(apiUrl))
    const posts = await res.json()
    return posts.map((post) => {
        return {
            params: {
                id: String(post.id)
            }
        }
    })
}

export async function getPostData(id) {
    const res = await fetch(new URL(`${apiUrl}/${id}/`))
    const post = await res.json()
    return { post }
}

componentsフォルダ

  • Post.jsファイルを作成して、取得したブログのタイトルと詳細画面へ遷移するリンクを生成する
import Link from "next/link"

const Post  = ( { post }) => {
    return (
        <div>
            <span>{`${post.id} : `}</span>
            <Link href={`/posts/${post.id}`}>
                <span className="cursor-pointer text-blue-500 border-b border-blue-500 hover:bg-gray-200">
                    {post.title}
                </span>
            </Link>
        </div>
    )
}

export default Post

pagesフォルダ

  • blog-page.jsファイルはAPIを実行して上記で作成したコンポーネントにデータを渡す処理をしている
import Layout from '../components/Layout'
import { getAllPostsData } from '../lib/posts'
import Post from "../components/Post"

const Blog = ({posts}) => {
    return (
        <Layout title="Blog">
            <ul className="m-10">
                {posts && posts.map((post) => <Post key={post.id} post={post} />)}
            </ul>
        </Layout>
    )
}

export default Blog

export async function getStaticProps() {
    const posts = await getAllPostsData()
    return {
        props: { posts }
    }
}   
  • posts/[id].jsファイルを作成して詳細ページを表示する
import Link from "next/link"
import Layout from '../../components/Layout'
import { getAllPostIds, getPostData } from "../../lib/posts"

export default function Post( { post } ) {
    if (!post) {
        return "<div>Loading・・・</div>"
    }

    return (
        <Layout title={post.title}>
            <p className="m-4">{`ID : ${post.id}`}</p>
            <p className="mb-8 text-xl font-bold">{post.title}</p>
            <p className="mb-10">{post.body}</p>
            <Link href="/blog-page">
                <span>戻る</span>
            </Link>
        </Layout>
    )
}

export async function getStaticPaths() {
    const paths = await getAllPostIds()
    return {
        paths,
        fallback: false
    }
}

export async function getStaticProps({ params }) {
    const { post: post } = await getPostData(params.id)
    return {
        props: {
            post
        }
    }
}