React-router и history.pushState не уверен в правильности использовании, можно ли так делать?
Использую React, React-router и Redux.
Суть вопроса: на сайте есть несколько страниц на которых можно включать всплывающие окна. Всплывающие окна это такие же страницы (они имеют свою ссылку), но отображаются поверх страницы.
При открытии такого окна, я меняю ссылку в браузере, но меняю не с помощью react-router, а стандартным методом в js history.pushState. Это сделано было для того, чтобы реакт роутер не словил изменение адреса и на странице не заменились компоненты согласно новому урлу.
Код работает, всё отлично, но задался вопросом правильно ли так делать? Подскажите, правильно ли я понимаю, что реакт-роутер не должен отлавливать такое изменение урла и это нормальное для него поведение?
RomanSS: суть проблемы в том, что вы используете роутер, но работаете с урл в обход его, чтобы избежать некоторых негативных последствий. Это костыли. Приведите конкретный пример, чтобы было понятнее где именно у вас проблема.
Anton Bobylev: Проблема в том, что я не могу запускать в модальном окне компоненты имеющие свою ссылку. Условно пусть это будут новости загружаемые в модальном окне. У каждой новости есть свой урл, поэтому при загрузки такого модального окна, нужно менять урл в браузере. Так как урл меняется получается, что страница загружает компонент с новостью и еще запускает модальное окно с этой же новостью. А мне нужно, чтобы загрузка произошла только в модальном окне, но при этом и сменился урл, а как закрыли модальное окно урл вернулся на прежнее. Такие модальные окна можно запустить на любой странице.
Anton Bobylev: Возможные варианты: 1) Если переходят по прямой ссылке, то грузится список новостей и сразу же поверх открывается модальное окно с новостью. 2) Если кликают на сайте в списке новостей на новость, то открывается модальное окно новости. Эти два варианта без проблем реализуются. Но есть третий вариант 3) Допустим на странице "О компании" (это может быть любая страница кроме "Список новостей") есть ссылка на какую-то конкретную новость. Мы не находимся в списке новостей, мы совершенно на другой странице. И когда мы нажимаем на эту новость, я не хочу чтобы страница "О компании" заменилась на "Список новостей" + поверх модальное окное новости. Нужно чтобы осталась страница "О компании" + поверех модальное окно с новостью. При этом ссылка была на страницу новости.
RomanSS: если вам нужно, чтобы ссылка в компоненте оставалась тойже, но при клике на нее не происходило перехода на соответствующий роут, воспользуйтесь перехватом навигации.
RomanSS: то есть при наличии в адресной строке браузера '/news/1' в одном случае должно отображаться App -> News -> Modal(1), а в другом App -> About -> Modal(1)? Как-то это... не консистентно.
Anton Bobylev: ну как таковой проблемы в архитектуре я не вижу, я думаю у вас тоже есть модальные окна, которые вы можете запускать на любой странице, хотя контент у них один и тот же). Тут просто добавляя удобство для пользователя, чтобы он мог копировать ссылку в браузере на модальное окно и скинуть её кому-то, столкнулся с этой проблемой. (хотя тут сложно назвать это модальным окном, это почти полноценная страница, которая естественно при прямом заходу будет открываться на правильной странице)
RomanSS: модальные окна - зло с точки зрения предоставления контента. Возможно вы добьетесь небольшого повышения быстродействия и снизите количество передаваемых данных, но с точки зрения архитектуры все будет неоднозначно. Зачем использовать реакт с его иммутабильностью и ререндерингом всего при малейшем изменении стейта и городить такие костыли как у вас?
Anton Bobylev: не согласен на счет модальных окон, всё зависит от типа контента в нём, и самого вида модального окна, ну это не суть. Последний вопрос не совсем понял, я как раз избавляюсь от ненужного рендера основного компонента по нескольку раз, а он не такой уж и маленький. Проще показать какую-то маленькую часть контента в модальном окне, чем постоянно пересоздавать большой компонент. Модальное окно это тоже самое что и любой компонент на странице, только весь акцент выделен на него, так как он поверх всего расположен.
Всё же правильнее при использовании react-router управлять адресной строкой только через него без хаков и костылей. Например, можно сделать как-нибудь так:
Согласен что правильнее делать через реакт-роутер, но пока хорошего решения не нашел. Спасибо за предложенный вариант, он слишком труден в поддержки кода.