URL でダイアログの状態を保持する React フック


Braid Dialog にインスパイアされた :

It’s recommended that you connect the Dialog’s open state to your router so that it can be closed via the browser’s back button.



この文を見たとき、なんてクールなアイデアだろうと思いました.すべてのエッジ ケースをキャプチャするフックを実装するのは困難でした.

基本的な例:

const [showModal, setShowModal] = useState(false)

<Button onClick={() => setShowModal(true)}>Open dialog</Button>

<Dialog
  title="Dialog Title"
  description={<Text tone="secondary">Optional description</Text>}
  open={showModal}
  onClose={() => setShowModal(false)}
>
  <Placeholder height={100} width="100%" />
</Dialog>


では、何ができるか見てみましょう



ダイアログが開いたら、履歴の新しいアイテム、たとえば ?dialog=true にプッシュする必要があります.パスの代わりにクエリ パラメータを使用するのは簡単です.ルータを設定する必要がないためです.ただし、URL の他のパラメータも保持する必要があります.

ユーザーが戻ると、履歴の変更をリッスンして状態を更新する必要があります (例: showModal ).

ダイアログが閉じられたら、履歴から 1 つの項目をポップする必要があります.または、もう 1 つアイテムをプッシュするか、現在のアイテムを置き換えることもできますが、これらはすべてブラウザの履歴を汚染します.

ユーザーがダイアログ リンク (例: https://example.com/some-path?dialog=true ) に直接移動する場合、フックは showModal の開始値を true に設定する必要があります.

ユーザーが直接リンクにアクセスした後にダイアログを閉じるときは、ポップの代わりにプッシュを使用する必要があります.そうしないと、ブラウザーに空白のページが表示されます.

ダイアログを表示できる場合、ダイアログには前提条件がある場合があります.たとえば、チェックボックス付きのアイテムのリストがあり、ユーザーがそれらを削除するためにいくつかのアイテムを選択すると、確認ダイアログが表示されます.そのため、項目が選択されていない場合はダイアログを表示できません.

ユーザーがダイアログ リンクに直接移動し、前提条件が false である場合、フックは、URL からフラグを削除し、新しい履歴項目を作成しないために履歴置換を使用すると想定します.

ユーザーが dialog を開き、前に移動してから前に移動すると、前提条件は false で、フックはユーザーをリダイレクトすることを想定しています - 履歴から1つのアイテムをポップします.

ふう



優れた UX には注意が必要です.フックは次のようになります.

const [showModal, setShowModal] = useUrlToggle(
  "dialog",
  false
  /*, precondition is optional third param */
);


このフック here のプロトタイプを実装しました.最適なコードではないかもしれませんが、私の目標は概念実証を行い、それが可能かどうかを確認することでした.