目次
はじめに
以前から、ちらちらと視界に入ってきてはいたものの、見てみぬふりをしてきた SWR という存在。
今回は自分のメモ的な内容になってしまいそうですが、SWR について調べたことを記事にしていこうと思います。
仕組み
公式からの引用になりますが、vercel が開発しているデータフェッチのためのライブラリで、SWR という名称の由来は HTTP キャッシュ無効化戦略である stale-while-revalidate のイニシャルからきているようです。
このことからもわかるように、SWR とはデータから取得してきたキャッシュを最適化するための手法になります。
仕組みを簡単になぞってみるとこのような感じになります。
- 1.キャッシュからすでに持っているデータを返す
- 2.裏側でデータの通信を行う(フェッチリクエスト)
- 3.最新のデータを返す
ログインの時とかに役立ちそう
利用方法
公式の方を見ていただければいいのですが、一応こちらの方にも簡単な利用方法を書いていきたいと思います。
インストール
yarn
yarn add swr
npm
npm install swr
簡単な使い方
import SWR from 'swr'
function Profile() {
/**
* data: fetcherによって解決された、指定されたキーのデータ
* error: fetcherによって投げられたエラー
* fetcher: データを返す非同期関数
*/
const { data, error } = SWR('/api/user/123', fetcher)
/**
* データの所得状態による処理
*/
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
// データをレンダリングする
return <div>hello {data.name}!</div>
}
公式より引用
カスタムフックも簡単に
カスタムフックでさまざまなコンポーネントなどで再利用可能にする。
function useUser(id) {
const { data, error } = SWR(`/api/user/${id}`, fetcher)
/**
* コンポーネントから渡されたidから該当するapiを取得して処理
* 取得したデータ、ローディングの状態、エラーを用意しておく
*/
return {
user: data,
isLoading: !error && !data,
isError: error,
}
}
↑ 作成したカスタムフックをコンポーネントで利用する。
function Avatar({ id }) {
const { user, isLoading, isError } = useUser(id)
if (isLoading) return <Spinner />
if (isError) return <Error />
return <img src={user.avatar} />
}
公式より引用
API オプション
先ほどは簡単に基本的な使い方のみでしたが、他にも複数のパラメーターと戻り値が用意されています。
const { data, error, isValidating, mutate } = SWR(key, fetcher, options)
パラメーター
- key: [必須] リクエストの一意のキー文字列 (または関数 / 配列 / null) (取得したい API)
- fetcher: [オプション] データを取得する Promise を返す関数
- options: [オプション] この SWR フックのオプションのオブジェクト
戻り値
- data: fetcher によって解決された特定のキーのデータ
- error: fetcher によって返されたエラー
- isValidating: リクエストまたは再検証の読み込みがある場合
- mutate(data?, options?): キャッシュされたデータを変更する関数
公式より引用
Next.js での利用
個人的には Next.js で Jamstack に作ることが多いので、ここが一番気になっていたところです。
公式から以下の説明があるように、SSG,SSR とは相性が良さそうです。
SWR と一緒に使えば、SEO 用にページを事前レンダリングしたり、クライアント側でのキャッシュ、再検証、フォーカストラッキング、定期的な再取得などの機能を実行する事ができます。
SWRConfig の fallback オプションを使用することで、事前に取得したデータをすべての SWR フックの初期値として渡すことができます。
export async function getStaticProps() {
// `getStaticProps` はサーバー側で実行されます
const article = await getArticleFromAPI()
return {
props: {
fallback: {
'/api/article': article,
},
},
}
}
function Article() {
// `data` は `fallback` を利用して常に利用可能です。
const { data } = SWR('/api/article', fetcher)
return <h1>{data.title}</h1>
}
export default function Page({ fallback }) {
// `SWRConfig` の範囲内の SWR フックは、設定の値を使用します。
return (
<SWRConfig value={{ fallback }}>
<Article />
</SWRConfig>
)
}
メリット
上記からもなんとなくわかるかと思うのですが、データの取得を行うときなど fetch をするときに、useEffect 内でわちゃわちゃと冗長になってしまう処理を SWR ならシンプルに処理が行えるようになるようですね。
なので、データの通信を行う時などには積極的に取り入れたい仕組みです。
参考
- https://swr.vercel.app/ja
- https://swr.vercel.app/docs/options
- https://zenn.dev/yukikoma/articles/17adad7fedd5af
- https://zenn.dev/uttk/articles/b3bcbedbc1fd00
- https://zenn.dev/mast1ff/articles/5b48a87242f9f0
- https://dev.classmethod.jp/articles/getting-started-swr-with-nextjs/
- https://codezine.jp/article/detail/13836
さいごに
引用引用ですみません。。
公式ドキュメントが日本語対応されているのが非常に助かりました。
個人的にはこうしてまとめる作業をしたことで勉強になりましたが、公式を見た方がいいかもしれません w
調べてみて勉強にはなったけれども、実際に使ってみないと有用性や細かいオプションについては使いこなせるようにならなそう。
ということで、実際に SWR を使ってみてどうだったかの感想もまたこのブログの記事にしていきたいなと思っております!