axios swr use-http の書きっぷり
今回は基礎編として、めちゃくちゃシンプルなサンプルを書いてみました。
ひとまずデータを取得するだけのサンプルです。
import { useEffect, useState } from "react";
import axios from "axios";
import useFetch from "use-http";
import useSWR from "swr";
type FloofData = {
image: string;
link: string;
};
const url = "https://randomfox.ca/floof/";
const fetcher = () =>
axios
.get<FloofData>(url)
.then(({ data }) => data)
.catch((e) => {
throw e;
});
function App() {
const { data: swrData, error: swrError } = useSWR<FloofData, Error>(
// ユニーク値ならなんでも良い
"/floof/",
fetcher,
);
const { data: fetchData, error: fetchError } = useFetch<FloofData>(
url,
undefined,
[],
);
const [axiosData, setAxiosData] = useState<FloofData | undefined>(undefined);
const [axiosError, setAxiosError] = useState<Error | undefined>(undefined);
useEffect(() => {
const callback = async () => {
try {
const data = await fetcher();
setAxiosData(data);
} catch (e) {
setAxiosError(e);
}
};
callback();
}, []);
return (
<div>
<div>{`swr data: ${JSON.stringify(swrData)}`}</div>
<div>{`swr error: ${JSON.stringify(swrError)}`}</div>
<div>{`use-http data: ${JSON.stringify(fetchData)}`}</div>
<div>{`use-http error: ${JSON.stringify(fetchError)}`}</div>
<div>{`axios data: ${JSON.stringify(axiosData)}`}</div>
<div>{`axios error: ${JSON.stringify(axiosError)}`}</div>
</div>
);
}
export default App;
上記のサンプルは api もフリーでパブリックなものを使っているので、そのまま貼り付けてもらえば動作すると思います。
自分もまだまだ理解しきれていないのですが、ざっくりと印象を書いてみると。
use-http
- ssr に対応しているため、onMount 時にデータを取得することができる
- Rest api だけでなく、GraphQL にも対応しているのがユニーク
- GET, POST, PUT などなんでも手軽に叩ける、ただし上記サンプルのように書くと GET が叩かれる
- とてもシンプルな仕様なためさくっとデータを取得したいときに便利、公式ドキュメントも読みやすい
use-http
というパッケージ名に対してuseFetch
をデフォルトで受け取るのが命名的にめちゃくちゃ気持ち悪い- エラーハンドリング周りがちょっと怪しい
swr
- こちらも ssr に対応している(いかにも vercel っぽい作り)
- こちらも GraphQL にも対応している
- GET 専用で使用できる
useSWR
の第一引数にキーとなる文字列を指定するのがユニーク、このキーがキャッシュや起動タイミングをうまいことやってくれるみたい- かなり複雑な引数の取り方をしたりと、シンプルそうに見えてそうでもない
use-http
は Api のスキーマが存在していて、各エンドポイントの url が確定している小規模なプロジェクトでさくっと使用するのに便利かなーと感じました。
swr
は 公式の Example が存在しているのですが。
「もうバケツリレーはやめよう!」といった内容が書かれていて、確かにキャッシュ周りの整備は良い感じになっている印象です。
が、一方で Atomic Design に落とし込むとこれだとうまくいかないため、どちらを取るか、うまい落としどころを見つける必要がありそうです。
今の現場では useSwr
の第 2 引数の fetcher に useCallback
で生成した関数を割り当てているのですが、使い方としてはちょっと怪しい感じが…。
スキーマから生成したクライアントの関数をそのまま割り当ててあげるのが無難かなーと思います。
両方とも ssr に対応しているため、Nextjs を使用したときに getServerSideProps
を書かなくて良いというのはメリットでありデメリットでもありかなーという印象です。
小規模なプロジェクトであれば特に問題ないのですが、大規模なプロジェクトになってくると pages の render が膨らむので、それを良しとするかどうかが分水嶺かなと思いました。
redux
と ssr の相性の悪さもあって、現時点でもまだこれという手法が固まりきっていないのかなーと、調べていて少し感じました。
あくまで個人的な結論ですが、csr のみであれば好きに組んで問題ないと思っています。
一方 ssr が絡むのであれば、無難に axios
あたりで組むのも全然アリじゃないかなーと思います。
React で ssr となれば、十中八九 Nextjs を使用することになると思うので、onMount の GET は axios
を使用してすべて getServerSideProps
に寄せる無難な構成で十分かなぁと。
ssr が絡んだ上で use-http
や swr
を使いこなすのはかなり難しそうです、自分ももう少し調べていこうと思います。