2001Yのプロフォール画像

2001Y@Y20010920T

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 (きれい!!)