swr と http client library(ky) の クエリパラメータ設定方法について
第一引数key
swrはkeyとしてURLを渡すことを基本している。このstringをcache keyとして内部で扱っている。
key is a unique identifier of the data (normally the API URL) and will be passed to fetcher.
URLにはクエリパラメータも含むことが期待される。通常はレスポンス結果が異なるからだ。
const { data } = useSWR('/api/data?uid=' + user.id, fetcher);
クエリパラメータの作成にはURLSearchParams
が便利である。
このURLSearchParams
を使うと以下のようにかける。
const fetcher = (url: string) => {
// 略
}
const { data } = useSWR(
"/api/data?" + new URLSearchParams({ uid: user.id }).toString(),
fetcher
);
fetcher
が受け取る引数はシンプルにstringとなっている。
ky options
HTTP client based on the browser Fetch API
であるkyもoptions
としてsearchParams
を渡すことができる。
Search parameters to include in the request URL. Setting this will override all existing search parameters in the input URL.
Accepts any value supported by URLSearchParams().
型定義は以下の通りURLSearchParams
と同様である。
searchParams?: string | {[key: string]: string | number | boolean} | Array<Array<string | number | boolean>> | URLSearchParams;
swrとkyのoptions
を組み合わせると以下のようになる。
import type { Options } from "ky";
const kyFetcher = (url: string, options: Options) => {
// 略
}
const { data } = useSWR(
[
"/api/data?",
{
searchParams: { uid: user.id },
},
],
kyFetcher
);
swrの第一引数は長さ2の配列となっており、kyFetcher
はそれぞれを受け取っている。以上のコードで問題なく動作する。
が、無駄な処理が発生している。
swr の object->key mapping
swrは第一引数keyがarrayだった場合に以下の関数でhash値(string)を算出している。
export default function hash(args: any[]): string
ここに渡ってくるargs[1].searchParams
はkyの内部処理(new URLSearchParamsを通して)で必ずstring化されるものだ。にも関わらずswrでもWeakMap
を活用してstring化されている。そもそもクエリパラメータなのだから最初の例のように単純なstringとして第一引数で渡されるべきなのだろう。しかし、keyのインターフェースを活用するために無駄なhash関数が実行されている。
方針案
- 妥協してarrayで渡す。
- URL(クエリパラメータ付き)stringの作成はfetcher関数に渡す前に完了する。