【JavaScript】【React】React Router v6でクエリ文字列を取得・変更する
はじめに
React Router v6を使っていて、クエリ文字列(?以降の文字列)を取得する必要があったため、少し調べてみました。そのメモです。
useSearchParams()
React Router v6でクエリ文字列を取得・変更するには、useSearchParams()
フックを使います。使い方はuseState()
に似ています。
const [searchParams, setSearchParams] = useSearchParams();
searchParams
にはURLSearchParams
オブジェクトが入ります。setSearchParams()
を使うことでクエリ文字列を変更できます。
URLSearchParamsオブジェクト
URLSearchParams
オブジェクトは、React Routerの一部ではなく、Web APIの一部です。以下のようなメソッドが用意されています。
メソッド | 機能 |
---|---|
append(name, value) | name=value を追加します。 |
delete(name) | name と関連付けられた値を削除します。 |
entries() | 名前と値の組を表すイテレータを返します。 |
forEach(callback) | 各名前と値の組に対してコールバック関数を呼び出します。 |
get(name) | name に対応する値を取得します。 |
getAll(name) | name に対応する値をすべて取得します。 |
has(name) | name が存在するかtrue /false で返します。 |
keys() | 名前を表すイテレータを返します。 |
set(name, value) | name=value をセットします。すでにname がある場合は置き換えます。 |
sort() | name で昇順に並べ替えます。 |
toString() | オブジェクトの内容をクエリ文字列にして返します。 |
values() | 値を表すイテレータを返します。 |
使用例
(1)クエリ文字列を取得する
クエリ文字列を取得するには、get()
またはgetAll()
を使います。
この例では、リンクに直接埋め込まれたname1
, name2
という名前を持つ値を取り出して表示します。name1
については対応するすべての値を表示します。
import { React, useState } from "react";
import ReactDOM from "react-dom";
import {
BrowserRouter,
Route,
Routes,
Link,
useSearchParams,
} from "react-router-dom";
const App = () => {
return (
<Routes>
<Route path="/" element={<TopPage />} />
<Route path="/test1" element={<Test1 />} />
<Route path="/test2" element={<Test2 />} />
</Routes>
);
};
if (document.getElementById("app")) {
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("app")
);
}
const TopPage = () => {
return (
<div>
<Link
to="test1?name1=value11&name1=value12&name2=value2"
>
テスト1
</Link>
/
<Link to="test2">
テスト2
</Link>
</div>
);
};
const Test1 = () => {
const [searchParams] = useSearchParams();
return (
<ul>
<li>name1 : {searchParams.getAll("name1").join()}</li>
<li>name2 : {searchParams.get("name2")}</li>
</ul>
);
};
(2)クエリ文字列を変更する
クエリ文字列を変更するには、useSearchParams()
の2番目の戻り値(ここではsetSearchParams()
を使用します)。setSearchParams()
に渡す値の形式は、この例のような{ key: value }
という組を持つオブジェクトのほかに、いくつかあるようです。
この例のコードは上の続きになっています。
フォームから入力されたkeyとvalueの組をクエリ文字列に付加すると同時に、リストとしてフォームの下側に表示します。
const Test2 = () => {
const [searchParams, setSearchParams] = useSearchParams();
const [key, setKey] = useState("");
const [value, setValue] = useState("");
const [query, setQuery] = useState({});
const handleKeyChange = (e) => {
setKey(e.target.value);
};
const handleValueChange = (e) => {
setValue(e.target.value);
};
const handleAppend = (e) => {
if (key === "" || value === "") {
return;
}
let q = { [key]: value, ...query };
setQuery(q);
setSearchParams(q);
};
const queries = [];
for (const [name, val] of searchParams.entries()) {
queries.push(name + ": " + val);
}
return (
<div>
key <input type="text" onChange={handleKeyChange} />
value <input type="text" onChange={handleValueChange} />
<button onClick={handleAppend}>追加</button>
<hr />
<ul>
{queries.map((s) => {
return <li key={s}>{s}</li>;
})}
</ul>
</div>
);
};
React Router v5以前では
React Router v5以前では、useSearchParams()
がありません。代わりにuseLocation()
とURLSearchParams
オブジェクトを使うことで、似たようなことが可能です。
const location = useLocation();
const searchParams = new URLSearchParams(location.search);
まとめ
React Router v6でクエリ文字列を取得・変更できるフックである、useSearchParams()
について調べてみました。React Router v6でないと使えないので注意が必要ですが、クエリ文字列の取得・変更が簡単に行えます。
それ以前のバージョンではuseLocation()
とURLSearchParams
オブジェクトを使うことで似たようなことが可能です。
ディスカッション
コメント一覧
まだ、コメントがありません