Мысль о редукс-башне

Что такое роутинг в React / Redux? По сути, это переключатель компонентов. Но большинству реальных приложений необходимо загружать данные, прежде чем показывать компонент, связанный с маршрутом, предотвращать уход с текущего маршрута, чтобы сохранить несохраненные данные, и проверять, вошел ли пользователь в систему перед входом в раздел администратора. Эти задачи можно выполнить с помощью механизма крючков. Ловушка ввода обрабатывает выборку данных и аутентификацию. Ловушка выхода полезна для грязной проверки и очистки чего-либо перед переходом страницы.

В этом посте я хотел бы сосредоточиться на хуках маршрутизации на стороне клиента, особенно в стеке React + Redux.

Использование response-router в реальном мире

Response-router - это без преувеличения стандарт де-факто как библиотека маршрутизации в экосистеме React. Если вы используете стек React + Redux, возможно, вы слышали это однажды.

Например, KeystoneJS использует комбинацию response-router и react-router-redux. Поскольку они используют его как переключатель компонентов, вставлять крючки некуда. Вместо хуков KeystoneJS использует redux-thunk для инициации выборки данных. В дополнение к этому, флаг загрузки в состоянии Redux полезен для предотвращения появления пустой страницы во время выборки данных. Поэтому, когда пользователь щелкает ссылку, он отправляет преобразователь и выполняется в промежуточном программном обеспечении преобразователя. Затем состояние флага меняется на загрузка и обратно в готово, когда загрузка завершается.

Приведу еще один пример. Вариант использования Recruit Technologies немного хакерский, но интересный. Они используют React + Redux + response-router + redux-async-loader. Redux-async-loader предоставляет промежуточное ПО для реактивного маршрутизатора, которое обертывает целевые компоненты компонентом более высокого порядка, который блокирует рендеринг дочерних компонентов до тех пор, пока не будет завершена выборка данных. Обратный вызов onEnter, предоставляемый response-router, используется для аутентификации. Это похоже на ловушку ввода, о которой я говорил выше, но как насчет выборки данных? К сожалению, это НЕ рекомендуется, так как это может привести к блокировке пользовательского интерфейса и его зависанию. onLeave - это обратный вызов, который выполняется при выходе из своего маршрута. Однако этот нельзя использовать для предотвращения переходов между страницами, поскольку он не может получить доступ к объекту маршрутизатор.

Возможно, вы понимаете, что это слишком сложно, но важно для приложений.

Сроки ходовых крючков

Я понял, что есть два кандидата на запуск крючков по таймингу; Компонент и маршрут. Перехватчик компонента вызывается, когда компонент монтируется или отключается. Перехватчик маршрута вызывается при входе в маршрут или выходе из него. Это то же время, что и смена местоположения. Вот пример кода, созданного с помощью response-router.

Эта маршрутизация работает хорошо. Хм действительно? Другая маршрутизация ориентирована на крючки.

Маршрут «A» имеет «PageA» с входным крюком «E-A» и выходным крюком «L-A». С другой стороны, маршрут «B» не имеет компонентов с входом и выходом из крюков. Что происходит, когда я перехожу из пункта А в пункт Б? Выполняется выходящий хук A, а затем вызывается входящий хук B. Без проблем. Но я запутался в B → C.Если выходящий крючок B является крючком компонента, я ожидаю, что входящий крючок C будет запущен, но страница B продолжает отображаться, а выходящий крючок B не выполняется даже при изменении местоположения . Это означает, что все перехватчики response-router являются перехватчиками маршрута, а не компонентами.

В дополнение к этому, к сожалению, обратный вызов onLeave не так полезен (объяснено выше). Даже если я использую setRouteLeaveHook с withRouter » HoC, это просто делегирование обратного вызова beforeunload браузера. . В конце концов, я не могу предотвратить переходы между страницами, не полагаясь на надоедливое диалоговое окно подтверждения. Невозможно перехватить изменение местоположения с помощью кнопки Назад или Вперед в браузере.

Асимметричный вход / выход из крюков и промежуточный маршрут

В redux-tower маршрут - это поток управления, содержащий запрос на показ компонента. Он не связан напрямую с компонентом. Промежуточный маршрут является полезным шаблоном, чтобы удерживать компонент и не запускать его уходящий крючок. Так как ловушка выхода выполняется до изменения местоположения, ловушка выхода выполняется перед следующей сменой компонента. Это асимметрично, потому что ловушка ввода выполняется при изменении местоположения.

Я предполагаю, что вы находитесь в «/ posts / 1». Чтобы отредактировать сообщение, перейдите в «/ posts / 1 / edit». Это изменение местоположения запускает маршрут «/ posts /: id / edit» и запускает функцию «edit» генератора. Из-за того, что это сага, компонент «PostEdit» отображается после завершения загрузки данных. Не забывайте, что выходящий обработчик dirtyCheck поставлен в очередь для более поздней замены компонента. Если вы попытаетесь вернуться к «/ posts / 1» без сохранения данных, изменение компонента в функции «show» Generator вызовет ловушку выхода, которая поставлена ​​в очередь. Обратите внимание, что ловушка выхода не вызывается во время изменения местоположения. Изменение компонента будет отменено, если ловушка «dirtyCheck» вернет false.

Чтобы пройти грязную проверку, давайте перед отъездом подумаем о случае сохранения. Когда вы нажимаете кнопку сохранения на странице редактирования, активируется маршрут «/ posts /: id / update» и выполняется функция генератора «update». Поскольку компонент «PageEdit» все еще отображается, ловушка выхода еще не вызывается, даже если местоположение изменено на «/ posts / 1 / update». Он ожидает завершения обновления и перенаправляет на «/ posts /: id». В пункте назначения перенаправления, которым является функция «show», вызывается ловушка выхода «dirtyCheck», но флаг dirty уже сброшен, изменение компонента в функции «show» не будет предотвращено в это время.

Идеальная модель маршрутизации

Честно говоря, отмечу обратную сторону моего выбора redux-tower. Функция show в приведенной выше маршрутизации redux-tower имеет два эффекта; загрузка почтовых данных и изменение компонента. В этом действии маршрута после загрузки данных выполняется ловушка выхода. Что это значит? Существует непреднамеренная задержка до срабатывания спускового крючка. Ожидание загрузки данных не требуется.

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