Next.jsにはファイル名を[id].tsx
にするだけで、動的なルーティングに対応できるDynamic Routesがあり、id名
すなわちパスパラメータを取得するためにrouter.query
を使うが、このrouter.query
にはクエリパラメータとパスパラメータの両方が含まれる。
// example.com/test?mode=dark
router.query // { id: "test", mode: dark }
通常であればパラメータ名を指定するので問題ないが、このようにページ遷移後にクエリパラメータを引き継ごうとすると、Dynamic Routesのパスパラメータがクエリパラメータとなって遷移してしまう。
//example.com/test?mode=dark
import Link from "next/link";
export default function Page() {
<Link href={{
pathname: "/",
query: { ...router.query },
}} >
<a>トップページに戻る</a>
</Link>
}
// example.com?mode=dark&id=test (&id=testがいらない!!)
機能的に支障が出ることは少ないが、あまり美しくないのでクエリパラメータのみを引き継ぎたい。
router.pathname
でパスパラメータを当てる前のパスを取得できるので、そこから取得したDynamic Routesのパスパラメータを省いたオブジェクトを作ることで、遷移後もクエリパラメータのみを引き継ぐことができた。
// example.com/[id]?mode=dark
import Link from "next/link";
import { useRouter } from "next/router"; //追加
export default function Page() {
const router = useRouter(); //追加
const dynamicRoutesName = router.pathname.split(/\[|\]/)[1]; //パラメータ(パス)を取得
var queryParams = JSON.parse(JSON.stringify(router.query)); //パラメータ(クエリ+パス)をディープコピー
delete queryParams[dynamicRoutesName]; //パラメータ(パス)を削除
return (
<Link href={{
pathname: "/",
query: { ...queryParams },
}} >
<a>トップページに戻る</a>
</Link>
)
}
// example.com?mode=dark (きれい!!)