1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Next.js アプリでURLのクエリ文字列は隠しつつ遷移先にパラメータを渡す

Posted at

本記事では分かりやすさを重視するため、F1 を題材として取り扱っています。

F1 Racing Teams 2021 - Ferrari, McLaren, Mercedes and more

Next.js における Link コンポーネントの基本的な使用方法は公式ドキュメントを参照してください。
next/link | Next.js

本題

例えば以下のように、URL には識別子を含めずに名前のみで構成したい、といった場合です。

URL例
https://yourhostname.com/Mercedes/Lewis-Hamilton

この URL は[オリジン]/[チーム名]/[ドライバー名]という構成になっています。
実際のところ、こういったケースではチーム IDドライバー IDも同時に遷移先に渡したい場合がほとんどだと思います。
チーム IDドライバー IDなどの識別子を受け取らない場合、遷移先ではチームやドライバーの情報を文字列で検索しなければならないからです。
プログラマーであれば「それは避けたい」と直感的に思うのでは無いでしょうか。

識別子を含める場合、URL は以下のようになると思います。

URL例
https://yourhostname.com/Mercedes/Lewis-Hamilton?teamId=1&driverId=1

少々ばかり冗長に見えますし、これでは名前のみで構成したいという目的が達成されていません。

コード例

この場合のコード例を以下に示します。

const url =
  `/${team.teamName}/${driver.driverName}`.replace(/\s/g, "-") +
  `?teamId=${team.teamId}&driverId=${driver.driverId}`;

return (
  <li key={url}>
    <Link href={url}>{driver.driverName}</Link>
  </li>
);

サンプルコード - github

パラメータはuseRouterをラップしたカスタムフックを自作し受け取っています。

import { useRouter } from "next/router";

const useParams = () => {
  const router = useRouter();

  return {
    teamId: router.query?.teamId ?? null,
    driverId: router.query?.driverId ?? null,
  };
};

export { useParams };

動作例

対処

state などを用いる方法もあると思いますが、今回は動的ルーティングを用いて解決しました。
next/link - Dynamic routes | Next.js

コード例

コード例を以下に示します。
Linkコンポーネントのhrefプロパティにクエリ文字列を付与した URL、asプロパティに表示したい URL を設定しています。

const asUrl = `/${team.teamName}/${driver.driverName}`.replace(/\s/g, "-");
const url = `/[team]/[driver]?teamId=${team.teamId}&driverId=${driver.driverId}`;

return (
  <li key={url}>
    <Link href={url} as={asUrl}>
      {driver.driverName}
    </Link>
  </li>
);

サンプルコード - github

動作例

URL からクエリ文字列が取り除かれているところ以外の違いはありあません。

無事に表示上の URL からクエリ文字列を隠蔽することに成功しました。

課題

ここまで実装すれば、目的は一応達成できています。
しかし課題も見えてきました。
まず、この実装では F5 を押されたときに元の画面を表示できません。
クエリ文字列が物理的に存在しないため、画面更新後にそれらを参照することができないためです。

感想

ReactRouter でのルーティングの方法が頭にこびりついていて、ファイルシステムベースでルーティングすることになかなか馴染めず苦戦しました。
なんて思っていたら ReactRouter も新バージョンが出てるみたいですね。
書き方が少し変わってるみたいなのでこちらもキャッチアップする必要がありそうです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?