【Next.js】クエリパラメータを渡しつつ遷移先のURLには表示させない方法
Next.jsにおいて、クエリパラメータを渡しつつ遷移先のURLには表示させずに参照する方法です。
あまりこういったケースはないかもしれませんが、以前ハマってしまったので方法をふたつ書いておきます。
⛰ 目的
- ページ遷移時にクエリパラメータをオブジェクトの形で渡したい
- 遷移先のURLにはクエリパラメータを表示させたくない
- 遷移先で渡されたクエリパラメータを参照したい
- 遷移先へ直リンクした際はクエリパラメータは存在しないようにしたい
📦 前提
- 特定の箇所で一時的に参照するため、Redux(などの状態管理ライブラリ)は使わない
-
/pages
配下のファイル同士の受け渡しのため、Propsは使えない
💡 結論
- Nextの
<Link>
コンポーネントで実現できる -
router.push()
で実現できる
Linkコンポーネントで実装する場合
/**
* 遷移前のページ
*/
import Link from "next/link";
// 受け渡すクエリパラメータ
const query = {
id: 1,
name: "yakkun",
};
export default function First() {
return (
<Link href={{ pathname: "second", query: query }} as="second">
<a>Secondへ遷移する</a>
</Link>
);
}
/**
* 遷移後のページ
*/
import { useRouter } from "next/router";
export default function Second() {
const router = useRouter();
return (
<ul>
<li>id:{" " + router.query.id}</li>
<li>name:{" " + router.query.name}</li>
</ul>
);
}
ブラウザでの挙動
- リンクをクリックして
/second
へ遷移 - URLにクエリパラメータが表示されていない
- 値は参照できている
-
直リンクの際は
undefined
になっている(遷移時にクエリパラメータが渡されるため)
上記が確認できました。
router.push()で実装する場合
/**
* 遷移前のページ
*/
import { useRouter } from "next/router";
// 受け渡すクエリパラメータ
const query = {
id: 1,
name: "yakkun",
};
export default function First() {
const router = useRouter();
const nextPage = () => {
router.push({ pathname: "second", query: query }, "second");
};
return <button onClick={() => nextPage()}>secondへ遷移する</button>;
}
/**
* 遷移後のページ
*/
import { useRouter } from "next/router";
export default function Second() {
const router = useRouter();
return (
<ul>
<li>id:{" " + router.query.id}</li>
<li>name:{" " + router.query.name}</li>
</ul>
);
}
ブラウザでの挙動
まぁ、さっきと同じです。
📖 解説
Linkの解説
Nextが提供している<Link>
コンポーネントは、通常href={"/hoge/huga"}
のようにパスを指定します。
ただこのhref
はオブジェクトも受け付けており、pathname
, query
というキーが使用できます。
それぞれ名称の通りパスとクエリパラメータを渡すことができます。
そして、今回重要なのはas
というオプションです。
as
には遷移先で表示するURLを渡すことができます。
// 省略
<Link href={{ pathname: "second", query: query }} as="second">
<a>Secondへ遷移する</a>
</Link>
);
}
つまり、どんなクエリパラメータを渡そうともas
により指定されたパスパラメータが遷移先のURLに表示されるという仕組みです。
上記の例では遷移先のURLは/second
となります。
router.push()の解説
Nextの<Link>
コンポーネントと同様に、SPAの挙動を取るrouter.push()
でも同様の実装ができます。
// 省略
const router = useRouter();
const nextPage = () => {
router.push({ pathname: "second", query: query }, "second");
};
return <button onClick={() => nextPage()}>secondへ遷移する</button>;
}
関数nextPage
を定義し、<button>
タグのonClick
イベントに渡しました。
nextPage
ではrouter.push()
にふたつの引数を渡しています。
第一引数にはurl
を受け付けるのですが、<Link>
同様オブジェクトでpathname
とquery
を渡すことができます。
そして、第二引数には<Link>
コンポーネントにおけるas
に相当する文字列を渡すことができ、遷移先のURLにどう表示されるかを指定することができます。
🖋 まとめ
ふたつとも同じ挙動を取るためどちらでも実現できます。
ただ<Link>
コンポーネントにはクリックイベントを指定できないため、遷移と同時に値を取得する処理などを挟む場合はrouter.push()
を使うとよいと思います。
また、非表示であれクエリパラメータはrouter
に格納されているため、遷移先で参照するにはuseRouter()
が必要になり、router.query.{hoge}
の形を取ることになります。
🦄 おわり
今回はクエリパラメータを渡しつつ遷移先のURLに表示させない方法をご紹介しました。
本来であればクエリパラメータやas
は動的ルーティングで活躍すると思うのですが、こういった使い方もできるよ〜というお話でした。
それではまた。
Discussion