SWRを使ってみた
📕Overview
データ取得のための React Hooks ライブラリ
“SWR” という名前は、 HTTP RFC 5861(opens in a new tab) で提唱された HTTP キャッシュ無効化戦略である stale-while-revalidate に由来しています。 SWR は、まずキャッシュからデータを返し(stale)、次にフェッチリクエストを送り(revalidate)、最後に最新のデータを持ってくるという戦略です。
✅SWR では、 コンポーネントはデータの更新を継続的かつ自動的に受け取ることができます。
そして、 UI は常に高速でリアクティブなモノになります。
import useSWR from 'swr'
function Profile() {
const { data, error, isLoading } = useSWR('/api/user', fetcher)
if (error) return <div>failed to load</div>
if (isLoading) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
この例では、useSWR フックは key 文字列と fetcher 関数を受け取ります。 key はデータの一意な識別子(通常は API の URL)で、fetcher に渡されます。 fetcher はデータを返す任意の非同期関数で、ネイティブの fetch や Axios のようなツールを使うことができます。
このフックは、リクエストの状態にもとづいて data と isLoading, error の三つの値を返します。
特徴
たった 1 行のコードで、プロジェクト内のデータ取得のロジックを単純化し、さらにこれらの素晴らしい機能をすぐに利用できるようになります:
速い、 軽量 そして 再利用可能 なデータの取得
組み込みの キャッシュ とリクエストの重複排除
リアルタイム な体験
トランスポートとプロトコルにとらわれない
SSR / ISR / SSG support
TypeScript 対応
React Native
SWR は、スピード、正確性、安定性のすべての面をカバーし、より良い体験を構築するのに役立ちます:
高速なページナビゲーション
定期的にポーリングする
データの依存関係
フォーカス時の再検証
ネットワーク回復時の再検証
ローカルキャッシュの更新(Optimistic UI)
スマートなエラーの再試行
ページネーションとスクロールポジションの回復
React Suspense
🧷summary
SWRってのは、どのように使えば良いかというと、fetch、axios、React Queryなどのように、APIとやりとりをする場面で使用します。
今回はこちらのAPIからデータを取得してみましょう。
npmで、swrを追加する。
npm i swr
SwrExampleというコンポーネントを作成して、APIからデータを取得してみましょう!
import useSWR from 'swr';
interface User {
id: number;
name: string;
}
const fetcher = (url: string) => fetch(url).then(res => res.json());
function Users() {
const { data: users, error } = useSWR('https://jsonplaceholder.typicode.com/users', fetcher);
if (error) return <div>An error has occurred: {error.message}</div>
if (!users) return <div>Loading...</div>
return (
<ul>
{users.map((user: User) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
export default function SwrExample() {
return <Users />;
}
App.tsxでimportしてビルドしてみる。
import SwrExample from './component/SwrExample'
export default function App() {
return (
<SwrExample />
)
}
成功すればこんな感じで、UIにAPIのデータを表示することができます🙌
Next14でも使ってみた!
多分、use client
つけるだけでいける気がする???
'use client';
import { table } from 'console';
import useSWR from 'swr';
interface User {
id: number;
name: string;
}
const fetcher = (url: string) => fetch(url).then(res => res.json());
function Users() {
const { data: users, error } = useSWR('https://jsonplaceholder.typicode.com/users', fetcher);
if (error) return <div>An error has occurred: {error.message}</div>
if (!users) return <div>Loading...</div>
return (
<table className='table-auto'>
<thead className='bg-cyan-500'>
<tr>
<th className='px-4 py-2'>ID</th>
<th className='px-4 py-2'>Name</th>
</tr>
</thead>
<tbody>
{users.map((user: User) => (
<tr key={user.id}>
<td className='border px-4 py-2'>{user.id}</td>
<td className='border px-4 py-2'>{user.name}</td>
</tr>
))}
</tbody>
</table>
);
}
export default function SwrExample() {
return <Users />;
}
page.tsx
でコンポーネントを読み込んでローカルサーバーを起動する。
import Image from "next/image";
import SwrExample from "./componets/swr_example";
export default function Home() {
return (
<div>
<SwrExample />
</div>
);
}
TailWindCSSで見た目を綺麗にしてみました。
🧑🎓thoughts
使ってみた感想ですが、今まで使っていた、useEffect
を使っていませんでした!
useEffectを使わずともAPIからデータを非同期に取得することができるので、とても便利だなと思いました。昔から、useEffectで書いていたので最近はこれで書くのが流行りなんですかね。
Discussion