仕組みから学ぶ Web
応用読了目安 15#状態管理#URL#キャッシュ#セッション#設計

状態をどこに置くか — URL に無いものは、共有できない

絞り込んだ一覧を同僚に送ったら、何も絞られていない画面が開いた。状態をどこに置くかは、何ができて何ができないかを決める。

この記事の進み方

What — 置き場所は4つある

同じ「状態」でも、置き場所によってできることが変わります

Compare状態の置き場所

コンポーネントの中。リロードで消える。

const [filter, setFilter] = useState({})

生存期間: ページを離れるまで
共有:     できない
復元:     できない
共有できる
できない
戻るで復元
されない
リロード耐性
消える
実装の軽さ
最も軽い
秘密を置けるか
端末をまたぐ
実装の重さ
  • 開閉状態、入力途中の値、ホバー。一時的なものはここでよい。
  • 冒頭の事故。絞り込みをここに置いたのが間違い。

どれが優れているかではなく、その状態に何を期待するかで選ぶ。共有したいなら URL、秘密にしたいならサーバー。

URL の状態
クエリ文字列やパスに埋め込まれた状態。共有とブックマークができる。
サーバー状態
サーバーが持つデータを、クライアントが写し取っているもの。キャッシュの一種。
クライアント状態
画面の都合だけで存在する状態。開閉、選択、入力途中。
ソース・オブ・トゥルース
その値の正が、どこにあるか。複数の場所に写しがあるとずれる。

「サーバーのデータ」と「画面の状態」は別物

混同されやすい2つです。

サーバーのデータ画面の状態
正はどこかサーバー画面
注文一覧、ユーザー情報開閉、選択中のタブ、入力途中
関心事取得・キャッシュ・再取得・古さ単純な保持

サーバーのデータを useState に入れて持つと、それはキャッシュです。キャッシュには「いつ古くなるか」「いつ取り直すか」という問題が付いてきます(network/caching と同じ構造)。

画面の状態と同じ扱いにすると、古いデータを表示し続けます。

Why — 置き場所が、できることを決める

URL に無いものは、存在しないのと同じ

Web の基本的な性質です。URL は「その画面を指すもの」であり、URL に含まれない状態は指せません

冒頭の事故で失われたのは、次の全部です。

  • 共有(同僚に送る)
  • ブックマーク
  • リロード
  • 戻る / 進む
  • 新しいタブで開く

これらは Web が最初から持っている機能です。状態を URL から外すと、それを自分で捨てることになります。

そして利用者は、それを不具合として報告しません。「このサイトはそういうものだ」と思うだけです。冒頭で誰も報告しなかったのは、そのためです。

「何を期待するか」から置き場所を決める

順序が重要です。先に技術を選ばない。

Figure置き場所を決める順序
  1. 1共有したいか
  2. 2その人だけの好みか
  3. 3サーバーのデータか
  4. 4一時的か
1/4
共有したいか同僚に送る・ブックマークする・戻るで復元する → **URL**

やりたいことから逆算する。ライブラリの選定は最後で、多くの場合そもそも要らない。

同じ値を2箇所に持つと、必ずずれる

URL にも useState にも同じ絞り込み条件を持つと、どちらが正かという問題が生まれます。

  • URL を直接編集された
  • 「戻る」で URL だけ変わった
  • 別の画面からリンクで来た

正を1つに決めます。 URL に置くなら、URL を読んで描画する。useState は持たない。

演習 — まず自分で判断する

確認 — ここまで読めたか

一覧の絞り込み条件は、どこに置くべきですか?

まず選ぶ(解答例は a〜d の記号で説明します)

確認 — ここまで読めたか

サイドバーの開閉状態は、どこに置くべきですか?

まず選ぶ(解答例は a〜d の記号で説明します)

読み終わりましたか?

読了にすると、これを前提とする記事がロードマップで開放されます。

この知識を使う実践ケース