Як синхронізувати параметри стану Redux та запитів url


77

У мене є веб-сторінка з панеллю пошуку. Панель пошуку має кілька полів введення: ідентифікатор, розмір, ...

Я хочу, коли користувач встановлює значення пошуку (наприклад: id = 123 і size = 45) і натискає кнопку пошуку:

  1. searchState у редукторі Redux слід оновити новими значеннями пошуку (id = 123 та size = 45)
  2. URL слід змінити на " http: // mydomain / home? Id = 123 & size = 45 "

А з іншого боку, якщо користувач змінює URL-адресу на http: // mydomain / home? Id = 111 & size = 22, тоді:

  1. searchState у редукторі слід змінити на нові значення пошуку (id = 111 та size = 22)
  2. Вхідні дані панелі пошуку інтерфейсу користувача повинні бути оновлені новими значеннями (id = 111 та size = 22)

Як досягти мети? Який маршрутизатор я повинен використовувати (response-router, redux-router, response-router-redux ot other)?

Відповіді:


71

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

Якщо ви дійсно хочете бачити зміни маршруту як дії, ви можете використовувати response-router-redux для двосторонньої синхронізації, але це не дасть вам параметрів у стані - лише поточного розташування. Єдиний варіант використання, якщо ви хочете записувати та відтворювати дії та оновлювати рядок URL-адреси під час їх відтворення.

Це ні в якому разі не потрібно - у більшості випадків достатньо лише безпосереднього використання React Router.


Привіт @ Дан, ми стикаємось з дуже подібною проблемою, як Антон. Ваша відповідь є багатообіцяючою, але нам важко знайти хороший приклад, коли React Router або навіть React Router у поєднанні з Redux змінюють стан лише одного компонента для декількох різних URL-адрес. У нашому випадку ми змінюємо хеш-тег, і він завжди повинен застосовуватися лише до одного компонента.
JoKer

1
Маєте єдиний маршрут, і використовуєте вбудований маршрутизатор для керування цим компонентом? Це справді окреме питання, не пов’язане з Redux, і ви можете поставити його окремо.
Ден Абрамов

Добре, я спробую створити нове запитання, де я детальніше поясню свою проблему. Дякую, що так швидко відповіли.
JoKer

1
Ось моє нове запитання. Було б дуже добре, якби ви могли поглянути. stackoverflow.com/questions/36722584 / ...
Joker

а як щодо використання параметрів маршруту у ваших селекторах? здається дещо безглуздим, коли доводиться надсилати це з компонента в селектор, і потенційна причина великої кількості дублювань
Бенджа,

17

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


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

Отже, я щойно опублікував redux-query-sync, щоб дозволити вам забезпечити функцію селектора для вибору значення зі стану, яке потім відображається у розташуванні вікна за вказаною назвою параметра. Щоб також дозволити йому синхронізуватися в іншому напрямку, таким чином, від URL до стану Redux (наприклад, коли програма спочатку завантажується), ви можете надати творця дії, якому буде передано значення параметра, щоб ваш редуктор міг відповідно оновити стан.


2

Ось спосіб, яким я займався з першим сценарієм:

  • Коли вхідне значення змінюється, його компонент ініціює зворотний виклик, який передається як підтримка з його контейнера.

  • Під час зворотного виклику контейнер відправляє дію, відповідальну за оновлення стану Redux, коли відбувається подія.

  • У рядку, який слідує за викликом дії, я використовую this.context.router.push()та передаю йому URL-адресу з правильним рядком запиту.

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

Щодо зворотного сценарію, я насправді не впевнений. Здається, що встановлення URL-адреси вручну спричинить повне перезавантаження, але я можу помилитися.

Що стосується того, який маршрутизатор використовувати, я використовую React Router сам по собі. Я насправді не знаходив цінності у використанні інших, і ця дискусія стала для мене ключовим фактором.


Проблема з цим підходом, як я бачу, полягає в тому, що як тільки у вас є кілька компонентів у контейнері, які змінюють url, він стає заплутаним безладом зворотних викликів та оновлення параметрів url. Це може бути зроблено у кожному компоненті, замість того, щоб використовувати зворотний виклик до контейнера ....
Alex Parij

2

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

Моє рішення було подібним до того, що описав кантера - мій стан маршрутизатора - це просто відображення стану форми. Це має додатковий бонус від того, що мені не потрібно відмовлятися від стану форми і повністю залежати від стану маршрутизатора.


У першому сценарії,

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

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

3) Я висуваю оновлений рядок запиту до стану маршрутизатора. Це суто для ефекту оновлення URL-адреси.


Для другого сценарію

1) У onEnterпідключенні кореневого Routeкомпонента я отримую доступний рядок запиту та аналізую його на початкові значення форми.

2) Я оновлюю свій магазин зі значеннями. Це лише для першого завантаження сторінки , і єдиний раз, коли стан маршрутизатора диктує стан форми.


Редагувати: це рішення не враховує випадок, коли ви повертаєтеся до історії браузера, оскільки URL-адреса не оновить ваш стан.



2

Я також нещодавно закінчив роботу над цією функцією для додатка моєї компанії. Ми хотіли додати різні пошукові запити до URL-адреси.

Кілька речей, якими я хотів би поділитися тут:

1) Ми використовували магазин Redux та маршрутизатор для реагування. Оскільки ми також використовували Typescript, ми в підсумку використали RouteComponentProps від response-router, щоб використовувати this.props.history.push () для оновлення URL-адреси.

2) Ми зберігали всі пошукові запити в магазині Redux. Процес оновлення магазину Redux, а потім URL-адреси такий:

Виберіть деякі параметри фільтрації в додатку => Дії відправлення, щоб оновити стан фільтрації в магазині Redux => оновити URL-адресу

3) Зрештою, ми також хочемо, щоб користувачі могли ввести URL-адресу із параметрами запиту, і вона оновить усі фільтри в додатку. Щоб це працювало, робочий процес ще простіший:

Користувач вводить URL-адреси => диспетчерські дії для оновлення стану Redux за допомогою параметрів запиту з URL-адреси. Оновлення стану Redux автоматично призведе до повторного відтворення в програмі, і всі фільтри будуть оновлені.

Тож найголовніше тут завжди підтримувати синхронізацію стану та URL-адреси Redux між собою.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.