Next.jsのWebアプリケーション内にて、ボタンを押したらAPIを叩いてデータを取得し描写するまでの流れを紹介いたします!
イメージとしてはこんな感じです。
See the Pen push_button by Taichi.Y (@tai72) on CodePen.
「キーワードを入力してください」の欄に適当な単語を入力してから「取得」ボタンを押すと、その単語に関する書籍のタイトルがいくつか表示されます。
それでは具体的な方法をこれからご紹介していきます!
自作のAPIを作成する
叩くAPIはなんでも良いのですが、ここではNext.jsのAPIを使用して自作していきたいと思います。
pages/api/ 配下に foods.tsx というファイルを作成し、下記のコードをコピペしましょう。
import type { NextApiRequest, NextApiResponse } from 'next'
// 返ってくるJSONオブジェクトの型
type Data = {
name: string;
description: string;
price: number;
}[]
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
if (req.method?.toLocaleLowerCase() !== 'get') {
return res.status(405).end()
}
res.status(200).json([
{
name: "焼肉",
description: "ハラミが好きです",
price: 3800,
},
{
name: "ステーキ",
description: "ミディアムが普通の焼き方です",
price: 5000,
},
{
name: "インドカレー",
description: "サグ系にハマっています",
price: 1400,
}
])
}
今回は「name, description, price」という3種類の値を持つオブジェクトをいくつか作成しました。
ぶっちゃけここはなんでも良いので、適当に中身を変更して構いません。
ローカル環境であれば http://localhost:3000/api/foods にアクセスして、次のような画面が表示されればOKです!
プラウンバターカレーもおすすめです。
ちゃんとAPIを叩けていますね。
これにて準備は完了です。
APIを叩く
続いて、データを取得してから描写するページのコードです。
まずは全体。
import { useState } from "react";
// 取得するJSONオブジェクトの型
type Food = {
name: string;
description: string;
price: number;
}
export default function Home() {
// 食事のオブジェクトを格納するやつ
const [foods, setFoods] = useState<Food[] | null>(null);
// ボタンを押した時に発火する関数
const onSubmit = async (): Promise<void> => {
try {
const res = await fetch('/api/foods')
.then(res => res.text())
.then(food => {
setFoods(JSON.parse(food))
})
} catch (err) {
alert(err)
}
}
return (
<>
<button type="submit" onClick={onSubmit}>取得</button>
<ul>
{foods ? foods.map((food: Food) => (
<li key={food.name}>
<p>
商品名: {food.name}<br />
説明: {food.description}<br />
値段: {food.price}
</p>
</li>
)) : <p>データなし</p>}
</ul>
</>
)
}
解説というほどでもないですが、区分ごとに見ていきます。
型の定義
// 取得するJSONオブジェクトの型
type Food = {
name: string;
description: string;
price: number;
}
APIを叩いて取得するデータの型を定義しています。
今回は返ってくるデータの型があらかじめ分かっているので、このように定義しています。
取得したデータを格納するやつ
const [foods, setFoods] = useState<Food[] | null>(null);
useStateフックを使用して、APIを叩いて取得するデータの格納先を定義しています。
初めは中身を null としているので、型は Food[] | null(Foodの配列もしくはnull) としています。
APIを叩く関数
// ボタンを押した時に発火する関数
const onSubmit = async (): Promise<void> => {
try {
const res = await fetch('/api/foods')
.then(res => res.text())
.then(food => {
setFoods(JSON.parse(food))
})
} catch (err) {
alert(err)
}
}
ここでは先ほど定義したAPIを使用してデータを取得し、food に格納しています(7行目)。
また同期処理を行うので async関数 を定義しています。
データの描写
return (
<>
<button type="submit" onClick={onSubmit}>取得</button>
<ul>
{foods ? foods.map((food: Food) => (
<li key={food.name}>
<p>
商品名: {food.name}<br />
説明: {food.description}<br />
値段: {food.price}
</p>
</li>
)) : <p>データなし</p>}
</ul>
</>
)
データ描写部分です。
3行目の<button>タグに、クリックした際に onSubmit関数を呼び出すよう設定しています。
また5 ~ 13行目にて、map()関数を使用して food の中身を出力しています。
ただし food の中身が null の場合もあるので、3項演算を使用して中身が null ではない場合のみ出力するようにしています。
上記のコードを実装した画面はこのようになります!
「取得」ボタンをクリックするとこのように表示が変わります。
ちゃんとデータを取得し表示することができています。
今回CSSは何も施していないので、適宜好みのデザインに変更してください。
まとめ
Next.jsにて、ボタンをクリックした時にAPIを叩いてデータを取得し、描写するまでの流れをピンポイントで紹介させていただきました。
今回はクライアント側でAPIを叩いてレンダリングする方法でしたが、ページをリクエストした時にサーバー側でAPIを叩いてレンダリングする方法は下記の記事で紹介しております。
ぜひ併せてご覧ください!
ご覧いただきありがとうございました!
コメント
コメント一覧 (1件)
[…] 【Next.js】ボタンを押したらAPIを叩いてデータを取得する(TypeScript) […]