Next.js getInitialPropsでページの非同期処理を学ぶ

2020年9月13日

こんにちは、Yuuichi(@WestHillWorker)です。

今回は前回作成した天気予報のAPIをgetInitialPropsを使って非同期データを取得、表示する部分について実践してみようと思います。

今回作成するものは以下都道府県別での天気情報を表示するものを作成します。

スポンサーリンク

getInitialPropsについて

Next.jsで標準APIとしてページのデータを取得する機能があり、それがgetInitialPropsと呼ばれる非同期関数を利用します。

pagesによってexportされたデフォルトのコンポーネントにのみ追加が可能で、それを他のコンポーネントに追加しても機能しないとのことです。

APIでid単位でもデータ取得可能にします

pages/api/wether.jsでid指定でデータを取得できるように修正します。

import wethers from '../../data/wethers.json';
export default (req, res) => {
  const { id } = req.query;
  // 一覧で取得する場合
  if (!id) return res.status(200).json(wethers);
  // idがリクエストパラメータに含まれる場合
  const wether = wethers.find(wether => wether.id == id);
  return res.status(200).json(wether);
};

data/wethers.jsonでidを追加

[
  {
    "id": 1,
    "wether": "はれ",
    "location": "東京都",
    "temperature": "30℃"
  },
  {
    "id": 2,
    "wether": "くもり",
    "location": "埼玉県",
    "temperature": "20℃"
  },
  {
    "id": 3,
    "wether": "あめ",
    "location": "千葉県",
    "temperature": "10℃"
  }
]

前回からidのプロパティを追加した形になります。

これでidからデータが引けるようになります。

APIを動かしてみましょう

以下のurlでidをパラメータに追加して、値に1を設定してみると..

http://localhost:3000/api/wether?id=1

以下のような表示になれば大丈夫です。

http://localhost:3000/api/wether?id=1

id=2とか3など他の都道府県の天気も取得できるはずです。

pages/にgetInitialPropsでfetchしてみましょう

fetchする際に必要なnpmライブラリがありますので、以下をinstallします。

$ npm install --save isomorphic-unfetch

isomorphic-unfetch クライアントとサーバー両方で機能するシンプルなfetchライブラリ。

index.jsでfetch

pages/index.jsでgetInitialPropsの非同期関数を利用して、APIをfetchして表示します。

import Layout from '../components/Layout';
import Link from 'next/link';
import fetch from 'isomorphic-unfetch';
const Index = props => {
  return (
    <Layout>
      <h1>天気予報 ニュース</h1>
      <ul>
        {props.wethers.map(wether => (
          <li key={wether.id}>
            <Link href="/wether/[id]" as={`/wether/${wether.id}`}>
              <a>{wether.location}</a>
            </Link>
          </li>
        ))}
      </ul>
    </Layout>
  )
};
Index.getInitialProps = async function () {
  const response = await fetch('http://localhost:3000/api/wether');
  const data = await response.json();
  console.log(data);
  // propsにwethersを設定
  return {
    wethers: data
  };
}
export default Index;

次にLinkでidを指定して、選択した都道府県のpagesを作成します。

[id].jsの作成

東京都などの選択したidの天気情報を表示するために、pages/wether/[id].jsを作成します。

import Layout from '../../components/Layout';
import fetch from 'isomorphic-unfetch';
const Wether = props => (
  <Layout>
    <h1>{props.wether.location}の天気</h1>
    <p>{props.wether.wether}</p>
    <p>{props.wether.temperature}</p>
  </Layout>
);
Wether.getInitialProps = async function (context) {
  const { id } = context.query;
  // 選択した都道府県の天気情報をAPIから取得する
  const response = await fetch(`http://localhost:3000/api/wether?id=${id}`);
  const wether = await response.json();
  console.log(`Fetched wether: ${wether.id} ${wether.location}`);
  return { wether };
};
export default Wether;

各wetherのページでもgetInitialPropsを利用して、Linkから送られたidを取得。

APIのリクエストパラメータにidを指定して、選択した都道府県の天気情報を表示します。

ブラウザで確認

$ yarn dev

ブラウザでlocalhost:3000にアクセスして確認してみましょう。

http://localhost:3000/

東京都・千葉県などを選択して、該当の天気情報が確認できたら完了です!

今回は、getInitialPropsでAPIをフェッチして表示する部分を学習しました。

getInitialPropsにつては、公式サイトにも詳細が記載ありますので、こちらを参照ください。

公式サイト:data fetching

お疲れ様でした!!