URLに状態を載せすぎて迷子になった話 ― Vue.jsで「どこに何を持つか」を考えてみました

こんにちは、さるまりんです 🐒🔧

以前の記事では、

JavaScriptでURLパラメータを安全に扱う方法を整理しました。

今回はその続きとして、

安全に扱えても、載せすぎると迷子になる

という話をしたいと思います。

Vue.jsで画面を作っていると、
「URLに状態を残したい」という気持ちが、だんだん強くなってきます。

作っていくうちに状態が増え、
気づいたら——

自分がどこで何を管理しているのか分からなくなる。

結局、自分はこの画面で
何をどうしたかったんだっけ?
という状態になりました。

URLは便利。でも、なんでもできるわけではない

URLに状態を入れると、確かに便利です。

  • リロードしても状態が戻る
  • URLを共有できる
  • デバッグがしやすい

この便利さがあるので、
つい、いろんなものを載せたくなります。

  • 表示モード(mode)
  • データ種別(type)
  • タブ状態(tab)
  • フィルタ条件(filter)
  • ソート条件(sort)

結果、URLはこんな姿に。

/list?mode=edit&type=a&tab=detail&filter=active&sort=desc

うーん……何をしようとしているんだ?

一応、読み解いてみます。

「一覧画面」で
「編集モード」で
「詳細タブ」を開いて
「有効なものだけ」絞り込んで
「降順で並べる」

……あれ?

  • 一覧って編集できたっけ?
  • 詳細タブって何?
  • type=a って何の a?

この時点で、

「今この画面、どういう状態なんだっけ?」

と、自分で分からなくなりました。

迷子になった!!

この頃のVue側のコードは、こんな感じでした。

watch: {
  mode() { this.syncUrl() },
  type() { this.syncUrl() },
  tab() { this.syncUrl() },
  filter() { this.syncUrl() },
  sort() { this.syncUrl() },
}

見た目は「ちゃんとしてそう」です。

画面の中で状態が変わると、
URLにも反映する——という意図でした。

でも、実際に起きていたのは:

  • どの変更がURLに影響するのか分からない
  • 変更 → URL更新 → 再描画 → watch発火、の連鎖
  • URLが正なのか、Vueのstateが正なのか分からない

はい。
完全に 状態の迷子 です。

「何が悪かったのか」を整理してみる

あとから冷静に考えると、
問題は意外とシンプルでした。

問題① URLに役割を持たせすぎていた

URLが、

  • 状態の保存場所
  • 状態の変更トリガー
  • 状態の正解(source of truth)

全部を兼ねてしまっていたのです。

問題② Vueの責務が曖昧だった

  • data
  • computed
  • watch

それぞれの役割が、URLと混ざっていました。

結果として、

URL / state / UI の境界が曖昧になって壊れていた

これが一番の原因でした。

「誰が何をするのか」を分けるって、
やっぱり大事なんですね。

改めて考えた「役割分担」

そこで、考え直しました。

URLに向いているもの

  • ページ番号
  • フィルタ条件(共有したいもの)
  • 表示モード(戻ってきたい状態)

👉 「画面を再現するための最低限」

URLに向いていないもの

  • 一時的なUI状態
    例:モーダルが開いているか、ツールチップの表示状態
  • タブの内部状態
    例:一覧タブの中で、どの行を一時的に選択しているか
  • 画面操作の途中経過
    例:入力途中のフォーム内容、ドラッグ中の位置、未確定の検索文字

👉 「今その場だけの状態」

Vue側の整理イメージ

Vue側で「何をどこに持つか」を、
かなり単純に考えるようにしました。

  • URL ← 共有したい状態
  • data ← 画面の今
  • computed ← 状態の派生
  • watch ← URLとstateをつなぐ最小限の橋

watchは「全部見る場所」ではなく、

URLと同期が必要なものだけを見る場所

にします。

迷子にならないための自分ルール

今回の反省から、
こんなルールを作りました。

  • URLは「地図」
  • Vueのstateは「現在地」
  • URLパラメータは少なめで!
  • watchが増えたら黄色信号

これを意識するだけで、
コードの見通しがかなり良くなりました。

おわりに

URLはとても強力です。
でも、やりすぎは禁物。

載せすぎると、自分が迷子になります。

安全に扱えるようになった次のステップは、

どこまで載せるかを決めること

でした。

同じように
「なんか複雑になってきたな……」
と思っている人が、
一度立ち止まって考えるきっかけになれば嬉しいです。

読んでくださってありがとうございました。
それではまた! 🐒🔧