応用読了目安 15 分#状態管理#URL#キャッシュ#セッション#設計
状態をどこに置くか — URL に無いものは、共有できない
絞り込んだ一覧を同僚に送ったら、何も絞られていない画面が開いた。状態をどこに置くかは、何ができて何ができないかを決める。
この記事の進み方
What — 置き場所は4つある
同じ「状態」でも、置き場所によってできることが変わります。
コンポーネントの中。リロードで消える。
const [filter, setFilter] = useState({})
生存期間: ページを離れるまで
共有: できない
復元: できない- 共有できる
- できない
- 戻るで復元
- されない
- リロード耐性
- 消える
- 実装の軽さ
- 最も軽い
- 秘密を置けるか
- —
- 端末をまたぐ
- —
- 実装の重さ
- —
- –開閉状態、入力途中の値、ホバー。一時的なものはここでよい。
- –冒頭の事故。絞り込みをここに置いたのが間違い。
どれが優れているかではなく、その状態に何を期待するかで選ぶ。共有したいなら URL、秘密にしたいならサーバー。
- URL の状態
- クエリ文字列やパスに埋め込まれた状態。共有とブックマークができる。
- サーバー状態
- サーバーが持つデータを、クライアントが写し取っているもの。キャッシュの一種。
- クライアント状態
- 画面の都合だけで存在する状態。開閉、選択、入力途中。
- ソース・オブ・トゥルース
- その値の正が、どこにあるか。複数の場所に写しがあるとずれる。
「サーバーのデータ」と「画面の状態」は別物
混同されやすい2つです。
| サーバーのデータ | 画面の状態 | |
|---|---|---|
| 正はどこか | サーバー | 画面 |
| 例 | 注文一覧、ユーザー情報 | 開閉、選択中のタブ、入力途中 |
| 関心事 | 取得・キャッシュ・再取得・古さ | 単純な保持 |
サーバーのデータを useState に入れて持つと、それはキャッシュです。キャッシュには「いつ古くなるか」「いつ取り直すか」という問題が付いてきます(network/caching と同じ構造)。
画面の状態と同じ扱いにすると、古いデータを表示し続けます。
Why — 置き場所が、できることを決める
URL に無いものは、存在しないのと同じ
Web の基本的な性質です。URL は「その画面を指すもの」であり、URL に含まれない状態は指せません。
冒頭の事故で失われたのは、次の全部です。
- 共有(同僚に送る)
- ブックマーク
- リロード
- 戻る / 進む
- 新しいタブで開く
これらは Web が最初から持っている機能です。状態を URL から外すと、それを自分で捨てることになります。
そして利用者は、それを不具合として報告しません。「このサイトはそういうものだ」と思うだけです。冒頭で誰も報告しなかったのは、そのためです。
「何を期待するか」から置き場所を決める
順序が重要です。先に技術を選ばない。
- 1共有したいか
- 2その人だけの好みか
- 3サーバーのデータか
- 4一時的か
1/4
共有したいか — 同僚に送る・ブックマークする・戻るで復元する → **URL**
やりたいことから逆算する。ライブラリの選定は最後で、多くの場合そもそも要らない。
同じ値を2箇所に持つと、必ずずれる
URL にも useState にも同じ絞り込み条件を持つと、どちらが正かという問題が生まれます。
- URL を直接編集された
- 「戻る」で URL だけ変わった
- 別の画面からリンクで来た
正を1つに決めます。 URL に置くなら、URL を読んで描画する。useState は持たない。
演習 — まず自分で判断する
確認 — ここまで読めたか
一覧の絞り込み条件は、どこに置くべきですか?
読み終わりましたか?
読了にすると、これを前提とする記事がロードマップで開放されます。