Состояние диалогов в SearchParams

web практики

Зачем вообще нужно через роутер?

По сути нужно делать через роутер в одном случае, это если хотите иметь возможность переходить на страницу по ссылке и чтобы диалог был сразу открыт.

Почему в SearchParams, а не по id из пути?

Есть логика

Во-первых, в этом есть логика. pathname это адрес страницы, а диалоги это то, что показывается поверх страниц.

Несколько диалогов на одной странице

Несколько диалогов на одной странице, это обычно первая проблема, с которой сталкиваешься, если привязываешься к id из пути. Обычно её решают через роутер, регистрируя, что один компонент открывает по нескольким адресам.

В случаи с SearchParams всё проще:

/products?dialog=editor&id=42
/products?dialog=details&id=42

Переиспользование диалога

Один и тот же диалог может быть на разных страницах. Не надо будет учить диалог открываться на всех них, достаточно научить открываться по нужному SearchParams:

/products?dialog=editor&id=42
/users/1/products?dialog=editor&id=42

Несколько параметров в адресе

Чем больше параметров надо передать диалогу через адрес, тем выше шанс, что вы сами придёте к SearchParams.

Создание:

/products?dialog=editor

Редактирование:

/products?dialog=editor&id=42

А может у нас сложный диалог, состоящий из нескольких табов, и мы ходим иметь возможность открывать диалог сразу на нужном:

/products?dialog=editor&id=42&tab=general

Закрытие диалога

Нужно закрыть диалог? Не надо знать адрес, на который вернуться, просто подчищаем параметры. В роутерах для React может выглядеть как-то так (если других SearchParams которые надо сохранить нет)

navigate(".");

Проблемы

Как и любого другого решения, имеются свои проблемы.

Search параметры самой страницы

На самой странице, на которой показываем диалог, могут быть свои собственные SearchParams, например search, sort, page. Нужно будет различать их и не потерять. Например, при закрытии диалога, не просто подчищать все параметры, а только те, что используются диалогом.

Доступность данных из API

Представьте список, полученный через бекенд.
Вы открываете диалог, в котором форма одной из таких записей.
При открытии диалога по клику на одной из записей списка, вы сохраняете выбранную запись во что-то типа preloadedItem и передаёте в props диалогу, чтобы не получать данные отдельно в нём.

Теперь у вас есть проблема, которую вы заметите, только переходя по ссылке с открытым диалогом на прямую. При переходе из списка, вы сохраняли preloadedItem, а при переходе по ссылке напрямую, он пуст. То есть всё-таки придётся иметь логику загрузки одной записи при открытом диалоге.

А самая большая проблема, если ваш API предоставляет данные только списком и нельзя получить по конкретному id. Поэтому, если вас попросили сделать диалоги так, чтобы они открывались по переданным ссылкам, данная задача может касаться не только фронтенда.