非同期での検索処理を実装したりするとHistoryAPIを使って動的にブラウザのURLを書き換えたりしますが、URLSearchParamsと組み合わせて使うといい感じに検索条件をSearchQueryに追加できそうだったのでメモ📝
SearchQueryをいい感じに追加する
以下のような感じで実装すると検索条件のSearchQuery(?foo=bar
)追加がappendParamToUrl
の引数にkey,valueを渡すだけでできるので便利そうでした。
URLSearchParams
で扱いやすいようにSearchQueryを文字列 - Objectに相互変換して更新し、history.replaceState
で元のURLを更新してあげる感じで実装してみました📝
// URLSearchParamsを使ってSearchQueryの文字列をObjectに変換 // "keyword=foo" -> { keyword: 'foo' } const urlSearchToObject = (search: string): { [k: string]: string } => { const params = new URLSearchParams(search); return Object.fromEntries(params); }; // URLSearchParamsを使ってObjectをSearchQueryの文字列に変換 export const objectToUrlSearch = (object: Record<string, string>): string => { const searchParams = new URLSearchParams(object); return searchParams.toString(); }; // SearchQueryに`?`を付けるか付けないかが紛らわしいので型レベルでチェックできるようにした type UrlQuery = `?${string}` | ""; // HistoryAPIを使ったURLの書き換え const replaceUrl = (path: string, query: UrlQuery) => { history.replaceState({}, "", `${path}${query}`); }; // 渡されたkey,valueをSearchQuery追記してURLに反映する const appendParamToUrl = (key: string, value: string) => { const searchParams = urlSearchToObject(location.search); searchParams[key] = value; replaceUrl(location.pathname, `?${objectToUrlSearch(searchParams)}`); }; const searchWord = "search word" appendParamToUrl("searchWord", searchWord) // -> example.com?foo=bar
おわりに
HistoryAPIとURLSearchParams便利ですね!!