SCALE — Build Lab

リロードしても同じセクションのまま

必須 状態保持

ブラウザでF5/Cmd+Rしてもページの「現在のタブ・セクション」が維持される。

なぜ必要?

初期状態に戻る → 何度も開き直し → ストレス。SPA全般で必須の体験品質。

どう実装する?

URL ハッシュ or クエリで現在状態を表現。ブラウザの戻る/進むも自動対応。

コード例
ts
// URL ハッシュで状態保持
function useHashState(key: string, defaultVal: string) {
  const [val, setVal] = useState(() => {
    const params = new URLSearchParams(location.hash.slice(1));
    return params.get(key) ?? defaultVal;
  });

  useEffect(() => {
    const params = new URLSearchParams(location.hash.slice(1));
    params.set(key, val);
    history.replaceState(null, '', '#' + params.toString());
  }, [val, key]);

  return [val, setVal] as const;
}

// 使い方: const [tab, setTab] = useHashState('tab', 'home');
関連機能
localStorage ストアパターン

リロードしても同じセクションのまま

:LiTarget: 何のために?

初期状態に戻る → 何度も開き直し → ストレス。SPA全般で必須の体験品質。

:LiSparkle: どう実装する?

URL ハッシュ or クエリで現在状態を表現。ブラウザの戻る/進むも自動対応。

:LiCode: コード例

// URL ハッシュで状態保持
function useHashState(key: string, defaultVal: string) {
  const [val, setVal] = useState(() => {
    const params = new URLSearchParams(location.hash.slice(1));
    return params.get(key) ?? defaultVal;
  });

  useEffect(() => {
    const params = new URLSearchParams(location.hash.slice(1));
    params.set(key, val);
    history.replaceState(null, '', '#' + params.toString());
  }, [val, key]);

  return [val, setVal] as const;
}

// 使い方: const [tab, setTab] = useHashState('tab', 'home');