Подтвердить что ты не робот

Как синхронизировать параметры состояния Redux и url

У меня есть веб-страница с панелью поиска. Панель поиска имеет несколько полей ввода: id, size,...

Я хочу, чтобы пользователь установил значения поиска (например: id = 123 и size = 45) и нажмите кнопку поиска:

  • searchState в редукторе Redux должен быть обновлен новыми значениями поиска (id = 123 и size = 45)
  • URL-адрес должен быть изменен на "http://mydomain/home?id=123&size=45"

А с другой стороны, если пользователь изменил URL на http://mydomain/home?id=111&size=22, когда:

  • searchState в редукторе следует изменить с новыми значениями поиска (id = 111 и size = 22)
  • Входы панели поиска пользовательского интерфейса должны обновляться новыми значениями (id = 111 и size = 22)

Как достичь цели? Какой маршрутизатор я должен использовать (реакция-маршрутизатор, редуктор-маршрутизатор, реакция-маршрутизатор-редукция и т.д.)?

4b9b3361

Ответ 1

Я бы предложил просто использовать React Router и не, сохраняя searchState в Redux. React Router будет вводить URL-параметры в ваши компоненты, и вы можете использовать их в mapStateToProps(state, ownProps) для расчета окончательных реквизитов.

Если вы действительно хотите видеть изменения маршрута в качестве действий, вы можете использовать react-router-redux для двухсторонней синхронизации, но он не даст вам параметры в состоянии - просто текущее местоположение. Единственный прецедент для него, если вы хотите записывать и воспроизводить действия, и обновлять строку URL-адресов при повторном воспроизведении.

Это отнюдь не требуется - в большинстве случаев достаточно просто использовать React Router.

Ответ 2

Вкратце: вы можете использовать redux-query-sync, чтобы сохранить параметры и поля URL в хранилище в синхронизации. Он работает без какого-либо маршрутизатора.


Более длинная история: Борясь с тем же вопросом, я вначале оценил ответ Дана Абрамова , предлагая (по-моему) рассмотреть URL как "второй магазин", часть состояния приложения вне магазина Redux. Но потом я обнаружил, что наличие двух видов "магазинов" затрудняет изменение кода, например. перемещать вещи от одного к другому, потому что каждый "магазин" имеет другой интерфейс. Как разработчик, я бы предпочел бы выбрать любое из полей в моем состоянии Redux и выставить их в URL-адресе, как если бы местоположение было маленьким окном (частью моего).

Следовательно, я только что опубликовал synchronx-sync, чтобы предоставить вам функцию выбора для выбора значения из состояния, которое затем отображается в местоположении окна с указанным именем параметра. Чтобы также синхронизировать его в другом направлении, таким образом, из URL-адреса в состояние Redux (например, когда приложение изначально загружается), вы можете предоставить создателю действия, которому будет передано значение параметра, поэтому ваш редуктор может соответствующим образом обновить состояние.

Ответ 3

Вот как я обрабатывал первый сценарий:

  • При изменении входного значения его компонент запускает обратный вызов, который был передан в качестве опоры из его контейнера.

  • В обратном вызове контейнер отправляет действие, ответственное за обновление состояния Redux при возникновении события.

  • В строке, следующей за вызовом действия, я использую this.context.router.push() и передаю ему url с правильной строкой запроса.

Я не уверен, что это правильный подход. Сначала мне было лучше обновить URL-адрес, потому что, на мой взгляд, строка запроса должна быть отражением состояния, а не хозяина.

Что касается обратного сценария, я действительно не уверен. Кажется, что ручная настройка URL-адреса приведет к полной перезагрузке, но я могу ошибаться.

Что касается того, какой маршрутизатор использовать, я использую React Router сам по себе. Я действительно не находил ценность в использовании других, и это обсуждение было для меня ключом.

Ответ 4

Недавно я закончил работу над подобной проблемой. Я использовал MobX как мой магазин и редукционный маршрутизатор в качестве моего маршрутизатора. (Я отлично справился с реактивным маршрутизатором, но мне нужно было отправить действие push вне компонента - redux, поскольку глобальный магазин отлично работает здесь)

Мое решение было похоже на то, что описала канона - мое состояние маршрутизатора - это просто отражение состояния формы. Это добавляет бонуса к тому, что вам не нужно останавливать состояние формы и полностью зависит от состояния маршрутизатора.


В первом сценарии

1) Я обновляю свой ввод формы, как обычно, который запускает повторную визуализацию в компоненте результатов.

2) В componentDidUpdate() компонента результатов я использую реквизиты формы для построения обновленной строки запроса.

3) Я нажимаю обновленную строку запроса в состояние маршрутизатора. Это чисто для обновления URL.


Для второго сценария

1) В hook onEnter на корневом компоненте Route я получаю доступную строку запроса и анализирую ее в значениях начальной формы.

2) Я обновляю свой магазин со значениями. Это только для первой загрузки страницы, и единственный раз, когда состояние маршрутизатора диктует состояние формы.


Изменить: это решение не учитывает случай, когда вы возвращаетесь в историю своего браузера, потому что URL-адрес не будет обновлять ваше состояние.