SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Next.jsの新しい概念を学ぶ

Next.jsの新常識「App Router」を学ぼう!

Next.jsの新しい概念を学ぶ 第1回

  • X ポスト
  • このエントリーをはてなブックマークに追加

サーバーで取得したデータを画面に表示する

 それでは、実際にhackernews-appを編集してみましょう。まずは、通信用の便利関数を用意しておきます(リスト7)。

[リスト7]app/_utils/hackerNews.js
/** Hacker Newsの人気・最新の記事500件の記事IDを取得する */
export async function getTopStories() {
  // (1)
  return fetch("https://hacker-news.firebaseio.com/v0/topstories.json", {
    next: { revalidate: 60 }, // (2) 1分経過するとキャッシュを破棄する
  }).then(
    (res) => res.json()
  );
}
/** 記事の詳細データを取得する */
export async function getItem(id) {
  return fetch(https://hacker-news.firebaseio.com/v0/item/${id}.json).then(
    (res) => res.json()
  );
}

 まず、Pages Routerに慣れた方は、appフォルダ内に便利関数のファイルを置いていることに戸惑われたかと思います。App Routerではこういったファイルも app フォルダ内に置けるようになりました。page.jslayout.js をはじめとした予約されたファイル名には特別な役目が与えられているため、その役割に見合った実装が必要ですが、それらのファイル名を避ければ、フォルダもファイルも自由に配置してOKです。特に、リスト7で配置した app/_utils フォルダのように、先頭にアンダースコアをつけたフォルダは、ルーティングから完全に除外されるので、UIと関係のないファイルを置く用途に適しています。

 関数の内部に目を向けると、サーバーで使用する処理ながら、(1)で fetch 関数を利用しているのが見えます。App Routerで動作しているサーバー側の処理の中では、Web標準とほとんど同じインターフェースの fetch 関数が整備されているので、ブラウザで学んだ知識がそのまま使用できます。ただし、App Routerの fetch は少しカスタマイズされている点に注意が必要です。同じURLからのGETリクエストは、デフォルトでキャッシュが効いて、2回目以降のアクセスでは1回目の処理結果をそのまま返すようになっています。時間経過で内容が変わりそうなものについては、(2)のように next.revalidate オプションでキャッシュを破棄する時間を指定すると良いでしょう。

 なお、前述しましたが、getTopStories() で取得できるのは記事のIDの配列だけです。そのため、タイトルなどを取得するためには、各IDを getItem() に渡して、記事データを入手する必要があります。

 それでは、リスト7の関数を使って、人気・最新の記事20件を表示するUIを作成してみましょう。app/top20/page.js を作成して、リスト8のコードを記述します。CSSファイルはサンプルコードに入っていますので、手元で動かしてみる場合はご利用ください( app/globals.css も上書きしてください)。

[リスト8]app/top20/page.js
import Link from "next/link"
import "./_style/top20.css"
import { getItem, getTopStories } from "../_utils/hackerNews";

export default async function Top20Page() {
  // (1) データをして加工する

  // 500件のデータを取得する
  const top500Ids = await getTopStories();
  // 上位20件のIDだけに絞り込む
  const top20Ids = top500Ids.slice(0, 20);
  // 上位20件の記事データを取得する
  const top20 = await Promise.all(top20Ids.map((id) => getItem(id)));
  // 記事データのIDとタイトルだけに絞り込み、
  // idとtitleのみのオブジェクトが20件入った配列にする
  const top20Summary = top20.map((item) => ({
    id: item.id,
    title: item.title,
  }));

  return (
    <div>
      <header>
        <h1>Hacker News Viewer</h1>
      </header>
      <div id="container">
        <div id="sidebar">
          <h2>Top 20</h2>
          <nav>
            <ul>
              {top20Summary.map((item) => (
                <li key={item.id}>
                  {/* (2) タイトルをリンクにする */}
                  <Link href={/top20/${item.id}}>{item.title}</Link>
                </li>
              ))}
            </ul>
          </nav>
        </div>
        <main>
          <div>(3) 本文をここに表示する</div>
          {/* {children} */}
        </main>
      </div>
    </div>
  )
}

 (1)では、リスト3の便利関数を使いながら、20件分の記事データの配列を作り出しています。記事データの配列は、リストとして表示し、(2)でリンクにしました。次回、このリンク先のページも作成します。リンクをクリックしたら、(3)の領域に本文を表示する予定ですが、少し特殊な仕組みを使う予定なので、今のところは仮置きのテキストを表示するだけにしておきます。

 では、実際に動かしてみましょう。ターミナルで npm run dev を実行して、http://localhost:3000/top20 にアクセスします(図6)。

図6:タイトルの一覧を表示した様子
図6:タイトルの一覧を表示した様子

 記事のリストをメニューとして表示できました。ちゃんと20件のリンクが並んでいますね。リンクをクリックしてみると、404 Not Found が表示されますが、まだ該当のページを作成していないので、期待通りの挙動です。

まとめ

 今回は、Next.js 13.4で安定版になったApp Routerについて、特徴を簡単に解説しつつ、サンプルコードの解説を始めました。React Server ComponentsはReactの経験が長い人であっても慣れるのに時間がかかる機能です。今後の連載を通じて親しめるものになるよう、解説します。

 次回はサンプルの続きを題材にして、layout.js の実践的な使い方を解説していきます。お楽しみに。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Next.jsの新しい概念を学ぶ連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 中川幸哉(ナカガワユキヤ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/17925 2023/07/05 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング