Closed5

swr と http client library(ky) の クエリパラメータ設定方法について

matamatanotmatamatanot

第一引数key

swrはkeyとしてURLを渡すことを基本している。このstringをcache keyとして内部で扱っている。

https://swr.vercel.app/#overview

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が便利である。
https://developer.mozilla.org/ja/docs/Web/API/URLSearchParams

このURLSearchParamsを使うと以下のようにかける。

const fetcher = (url: string) => {
  // 略
}
const { data } = useSWR(
  "/api/data?" + new URLSearchParams({ uid: user.id }).toString(),
  fetcher
);

fetcherが受け取る引数はシンプルにstringとなっている。

matamatanotmatamatanot

ky options

HTTP client based on the browser Fetch API

であるkyもoptionsとしてsearchParamsを渡すことができる。
https://github.com/sindresorhus/ky#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と同様である。
https://github.com/sindresorhus/ky/blob/ab134cd93659340681029c4525d7837b5cf90332/index.d.ts#L237

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はそれぞれを受け取っている。以上のコードで問題なく動作する。

が、無駄な処理が発生している。

matamatanotmatamatanot

swr の object->key mapping

swrは第一引数keyがarrayだった場合に以下の関数でhash値(string)を算出している。
https://github.com/vercel/swr/blob/0.3.9/src/libs/hash.ts

export default function hash(args: any[]): string

ここに渡ってくるargs[1].searchParamsはkyの内部処理(new URLSearchParamsを通して)で必ずstring化されるものだ。にも関わらずswrでもWeakMapを活用してstring化されている。そもそもクエリパラメータなのだから最初の例のように単純なstringとして第一引数で渡されるべきなのだろう。しかし、keyのインターフェースを活用するために無駄なhash関数が実行されている。

matamatanotmatamatanot

方針案

  • 妥協してarrayで渡す。
  • URL(クエリパラメータ付き)stringの作成はfetcher関数に渡す前に完了する。
このスクラップは2022/10/08にクローズされました