この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは!DA(データアナリティクス)事業本部 サービスソリューション部の大高です。
Next.jsと同じチームによって作成されている、データ取得のための React Hooks ライブラリとして「SWR」というライブラリがあります。
今回はこのライブラリの一番基本の部分をNext.jsのプロジェクトで試してみたいと思います。
SWRとは
公式サイトにも以下のように記載されていますが「SWR」という名前はHTTPキャッシュ無効化戦略であるstale-while-revalidate
に由来しています。
“SWR” という名前は、 HTTP RFC 5861 で提唱された HTTP キャッシュ無効化戦略である stale-while-revalidate に由来しています。 SWR は、まずキャッシュからデータを返し(stale)、次にフェッチリクエストを送り(revalidate)、最後に最新のデータを持ってくるという戦略です。
この考え方の仕組みにより、データが高速に返却され、更に自動で再フェッチ(revalidate)されるようになっています。
データの自動再フェッチ(revalidate)に関しては下記のページに詳細が記載されていますが、とても良いですね!
他にも、以下のような特徴を備えています。
- Next.js の SSR / ISR / SSG サポート
- TypeScript 対応
- React Native 対応
実際に試してみる
では、実際に公式のGetting Startedを見ながら試してみたいと思います。
対象プロジェクトの作成
まずはNext.jsのプロジェクトを作成しておきます。プロジェクト名はhello-swr
としました。
% yarn create next-app --typescript
yarn create v1.22.17
[1/4] ? Resolving packages...
[2/4] ? Fetching packages...
[3/4] ? Linking dependencies...
[4/4] ? Building fresh packages...
success Installed "create-next-app@12.0.7" with binaries:
- create-next-app
✔ What is your project named? … hello-swr
インストール
プロジェクトhello-swr
を作成したら、ディレクトリ移動をしてSWRをインストールします。
% cd hello-swr
% yarn add swr
yarn add v1.22.17
[1/4] ? Resolving packages...
[2/4] ? Fetching packages...
[3/4] ? Linking dependencies...
warning "next > styled-jsx > @babel/plugin-syntax-jsx@7.14.5" has unmet peer dependency "@babel/core@^7.0.0-0".
[4/4] ? Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ swr@1.1.2
info All dependencies
└─ swr@1.1.2
✨ Done in 1.08s.
サンプル作成
インストールしたら、 公式ドキュメントのサンプル「基本的な使用法」を参考に、index.tsx
を以下のように書き換えてサンプルを作成してみます。
pages/index.tsx
import type { NextPage } from "next";
import useSWR from "swr";
import styles from "../styles/Home.module.css";
const fetcher = (url: string) => fetch(url).then((res) => res.json());
const Home: NextPage = () => {
const { data, error } = useSWR(
"https://api.github.com/repos/vercel/swr",
fetcher
);
if (error) return <div>An error has occurred.</div>;
if (!data) return <div>Loading...</div>;
return (
<div className={styles.container}>
<main className={styles.main}>
<h1 className={styles.title}>{data.name}</h1>
<p className={styles.description}>{data.description}</p>
<p>
<strong>? {data.subscribers_count}</strong>{" "}
<strong>✨ {data.stargazers_count}</strong>{" "}
<strong>? {data.forks_count}</strong>
</p>
</main>
</div>
);
};
export default Home;
このサンプルではhttps://api.github.com/repos/vercel/swr
にリクエストした結果のJSON情報を画面に表示しています。また、リクエスト中にはLoading...
、リクエストエラーの場合にはAn error has occurred.
と表示されるようになっています。
実際に実行すると、このような感じに表示されます。
APIレスポンスが早く、パッと見た感じでは通常のAPI呼び出しと違いが分かりづらいので、少しコードを変えてみます。
pages/index.tsx
import type { NextPage } from "next";
import useSWR from "swr";
import styles from "../styles/Home.module.css";
function sleep(msec: number) {
return new Promise((resolve) => {
setTimeout(resolve, msec);
});
}
const fetcher = (url: string) =>
fetch(url).then(async (res) => {
sleep(5000);
return res.json();
});
const Home: NextPage = () => {
const { data, error } = useSWR(
"https://api.github.com/repos/vercel/swr",
fetcher
);
if (error) return <div>An error has occurred.</div>;
if (!data) return <div>Loading...</div>;
return (
<div className={styles.container}>
<main className={styles.main}>
<h1 className={styles.title}>{data.name}</h1>
<p className={styles.description}>{data.description}</p>
<p>
<strong>? {data.subscribers_count}</strong>{" "}
<strong>✨ {data.stargazers_count}</strong>{" "}
<strong>? {data.forks_count}</strong>
</p>
</main>
</div>
);
};
export default Home;
今度は、リクエスト時に5秒ほど待ってからレスポンスを返すようにしてみました。
こちらを試すと、最初の5秒は以下のようにローディング表示がされ、
その後に以下のように表示が自動で切り替わります。
また、このデータがキャッシュされるのでリロードしてもリクエスト結果が変わらない限り、初期表示としてこの画面が即時表示されるようになります。(毎回5秒を待つことはありません)
まとめ
以上、データ取得のための React Hooks ライブラリ「SWR」をNext.jsで試してみました。
今回は一番基本の部分だけでしたが、これだけでもコードの書き方としてかなり楽になると感じました。また、キャッシュ無効化戦略に基づいた仕組みもよく、高速に描画ができるのが良いなと思いました。今後、もう少し別のオプションなども含めて試してみたいと思います。
どなたかのお役に立てば幸いです。それでは!