目次
こんにちは!
今日のチュートリアルでは、Next.js を使用してシンプルかつ強力なブログを作成する旅に乗り出します。
Next.js を初めて使用する場合でも、基礎をさらに磨きたいと考えている場合でも、このガイドはあなたに合わせて作成されています。
プロジェクトのセットアップ方法だけでなく、フォルダー構造、サーバー側レンダリングなどについても説明します。
完全なリポジトリはここで見つけることができます
さっそく飛び込んでみましょう!
まず、次のコマンドを使用して Next.js アプリを設定しましょう。
npx create-next-app@latest blog-example
完了したら、新しく作成したプロジェクトに移動します。
cd blog-example
このガイドではyarn
使用していますが、 npm
またはpnpm
自由に使用してください。
yarn dev
ここで、 http://localhost:3000にアクセスすると、デフォルトの Next.js テンプレート ページが見つかります。
この時点で、Next.js アプリの構造を理解すると有益です。フォルダーのレイアウトを視覚的に表現した次の画像を参照してください。
/app/api/posts/route.js
内に、ブログ投稿用のダミー API を設定します。ここで、 next: { revalidate: 60 }
、60 秒ごとにデータを再検証することを指定します。
再検証は、データ キャッシュを消去し、最新のデータを再フェッチするプロセスです。これは、データが変更され、最新の情報を確実に表示したい場合に便利です。
キャッシュされたデータは、次の 2 つの方法で再検証できます。
- 時間ベースの再検証: 一定の時間が経過した後にデータを自動的に再検証します。これは、頻繁に変更されず、鮮度がそれほど重要ではないデータに役立ちます。
- オンデマンド再検証: イベント (フォーム送信など) に基づいてデータを手動で再検証します。オンデマンド再検証では、タグベースまたはパスベースのアプローチを使用して、データのグループを一度に再検証できます。これは、最新のデータをできるだけ早く表示したい場合 (ヘッドレス CMS のコンテンツが更新された場合など) に便利です。
時間ベースの再検証
一定の間隔でデータを再検証するには、
fetch
のnext.revalidate
オプションを使用して、リソースのキャッシュ有効期間 (秒単位) を設定します。
以下に例を示します。
import { NextResponse } from 'next/server' export async function GET() { const res = await fetch('https://dummyjson.com/posts', { next: { revalidate: 60 }, }); const data = await res.json(); return NextResponse.json(data); }
サーバーから投稿を取得して表示するコンポーネントPostsPage
を作成しましょう。ミニマルにスタイリングしましたが、自由にアレンジしてください。
export default async function PostsPage() { const res = await fetch('http://localhost:3000/api/posts'); const { posts } = await res.json(); return ( // Styles are for readability; customize as you wish! <div> <h1>All Blog Posts</h1> <hr style={{ width: '220px' }} /> <div style={{ paddingTop: '40px' }}> {posts.map(post => ( <article key={post.id}> <h2>{post.title}</h2> <p style={{ paddingBottom: '30px'}}>{post.body}</p> </article> ))} </div> </div> ); }
これまでのところ、記事のリストが表示されているはずです。
各投稿タイトルをクリックできるようにするには、Next.js からLink
コンポーネントを追加します。
import Link from 'next/link'; export default async function PostsPage() { // ... rest of the code return ( <div> // ... rest of the code <div style={{ paddingTop: '40px' }}> {posts.map(post => ( <article key={post.id}> <Link href={`posts/${post.id}`}> <h2>{post.title}</h2> </Link> <p style={{ paddingBottom: '30px'}}>{post.body}</p> </article> ))} </div> </div> ); }
Next.js API ルートでは、ID に基づいて特定の投稿を取得します。
import { NextResponse } from 'next/server' export async function GET(request, { params }) { const { id } = params; const res = await fetch(`https://dummyjson.com/posts/${id}`, { next: {revalidate: 60} }); const post = await res.json(); return NextResponse.json({ post }); }
個々の投稿を表示するには、Next.js のサーバー コンポーネントとクライアント コンポーネントの違いを理解することが重要です。
指定されたコンポーネントSinglePost
、クライアント側のデータ取得を使用します。
これは基本的に、ページがレンダリングされた後にデータがクライアントでフェッチされることを意味します。パフォーマンスを犠牲にすることなく、豊かな対話性を実現します。詳細については、React Essentials の Next.js ドキュメントを参照してください。
クライアント コンポーネントを使用すると、アプリケーションにクライアント側の対話性を追加できます。 Next.js では、サーバー上で事前レンダリングされ、クライアント上でハイドレートされます。クライアント コンポーネントは、 Pages Routerのコンポーネントが常に動作してきた方法であると考えることができます。
'use client' import Link from 'next/link'; import { useEffect, useState } from 'react'; export default function SinglePost({params}) { const [post, setPost] = useState(null); const fetchPost = async (id) => { const res = await fetch(`http://localhost:3000/api/posts/${id}`); const {post} = await res.json(); post && setPost(post); } useEffect(() => { fetchPost(params.id); }, []) return ( <div style={{ paddingTop: '20px', paddingLeft: '20px' }}> <Link href='/'>Back to home</Link> <div style={{ paddingTop: '50px' }}> <article> <h1 style={{ paddingBottom: '10px' }}>{post?.title}</h1> {post?.tags.map((tag, index) => <span style={{ fontWeight: 'lighter' }} key={index}>{tag} | </span>)} <br/> <p style={{ paddingTop: '10px' }}>{post?.body}</p> </article> </div> </div> ) }
これで、記事の詳細が表示されるはずです。スタイルの欠如を許してください!
ヒント:ユーザー エクスペリエンスを向上させるには、読み込みコンポーネントの追加を検討してください。 Next.js は、読み込み UI とストリーミングを備えた組み込みソリューションを提供します。コンテンツの準備ができるまで読み込みスピナーを表示するのに役立ちます。 UI の読み込みとストリーミングに関するこの公式ガイドをさらに詳しく学習してください。
例えば:
// You can add any UI inside Loading, including a Skeleton. export default function Loading() { return <LoadingSkeleton />}
Next.js アプリケーションの構築は、楽しくもあり、勉強にもなります。
私たちは、プロジェクトのセットアップ、フォルダー構造の管理、ブログ投稿の一覧表示、個々の投稿の紹介、さらには読み込み状態についても学習しました。
Web 開発コミュニティにおける Next.js の急速な成長に伴い、ここで学んだスキルは非常に貴重です。
この基盤を拡張して、さらに多くの機能を探索し、楽しくコーディングしてください。
記事のデータにはDummyJsonを使用しました
記事の作成にはStackEditを使用しました
貴重なお時間を割いて学習に取り組んでいただき、ありがとうございました。あなたのフィードバックは非常に貴重です。この投稿に追加や修正がある場合は、ご連絡ください。
dev.toコミュニティ@leandro_nnzまでご連絡ください。
hackernoon.comコミュニティ@leandronnz
Twitter @digpollution
乾杯!