Хуки, несомненно, являются будущим идиоматического React. Как руководитель группы разработки программного обеспечения, я должен следить за тем, чтобы моя команда всегда была в курсе современных технологий, когда они имеют смысл. Что касается хуков, моя команда уже начинает применять их в новых проектах. Таким образом, я подумал, что было бы полезно погрузиться в некоторые из последних функций, которые сообщество формирует вокруг них.

Парадигма хуков позволяет всем компонентам быть функциональными компонентами, а преобразование из компонента без состояния в компонент с локальным состоянием происходит без проблем. С введением хуков в модуль react-redux то же самое можно сказать и о компонентах, подключенных к хранилищу (или о том, что мы называем «контейнерами»).

Рассмотрим связный компонент в парадигме pre-hooks:

Поскольку моя команда использует Typescript для обеспечения безопасности типов, в этом сценарии мы создаем компонент, определяем интерфейс для типов, которые уже были определены (в генераторе действий redux), которые действуют как определение типа для свойств компонента, а затем мы оборачиваем компонент в связанный компонент более высокого порядка, который принимает две функции: одна для отображения состояния на соответствующие интерфейсы prop, а вторая для отображения любых функций, которые мы хотим отправить, в соответствующий интерфейс prop. Мы не только переопределяем наши интерфейсы без надобности и пишем дополнительные функции для сопоставления сущностей с этими интерфейсами (которые мы склонны переписывать для каждого контейнера, который должен использовать те же сущности), но мы также загрязняем виртуальную DOM упакованными компоненты, затрудняющие осмотр. Рассмотрим виртуальный DOM для этого контейнера, проверенный с помощью инструментов React в браузере:

При осмотре этой виртуальной DOM вы можете увидеть, что у нас есть исходный провайдер, который обертывает все приложение, чтобы связать хранилище с нашим приложением, за которым следуют 2 подключенных компонента (контейнера), первый - это контейнер приложения родительского уровня, а второй - наш контейнер навигации, упомянутый в листинге 1. Вы заметите, что каждый подключенный компонент создает 3 уровня в дереве компонентов виртуальной DOM: 1) экспорт компонента по умолчанию после того, как он был заключен в оболочку поставщиком контекста 2) сам поставщик контекста исходящий от функции «connect» в react-redux 3) фактический компонент, который вы намеревались подключить. Как видите, это загрязняет виртуальную DOM потенциально ненужными компонентами в дереве с точки зрения декларативного программирования. Этот шаблон также создает возможность ошибки, если компонент, который вы импортируете в свое приложение, является фактическим базовым компонентом, а не экспортом по умолчанию, созданным путем обертывания этого компонента компонентом соединения более высокого порядка. Итак, можем ли мы сделать лучше?

React-redux реализовал новые хуки в своей библиотеке, чтобы заменить эту оболочку подключения (убедитесь, что у вас установлена ​​версия 7.1.0 или выше, и объявления установленных типов совпадают, если вы используете Typescript). Это ловушка useSelector и ловушка useDispatch. Хук useSelector возвращает значение из хранилища, предоставленного во всеобъемлющей оболочке Provider. Это значение будет обновляться каждый раз при обновлении магазина и вызывать повторный рендеринг в вашем компоненте. Хук useDispatch предоставляет функцию отправки, которая связана с хранилищем, указанным во всеобъемлющей оболочке Provider. Используя эти крючки, мы можем упростить наш подключенный компонент, как показано ниже:

В этом коде гораздо меньше шаблонов, и его легче рассуждать. Это исключает возможность импорта неправильного компонента, поскольку в этом файле есть только один экспортируемый компонент. Вам также не нужно повторно объявлять типы для функций селектора и диспетчеризации, поскольку они подразумеваются генераторами / селекторами действий. Использование хуков также обеспечивает дополнительное преимущество более легкого рефакторинга в случае, если вы используете неподключенный компонент и внезапно вам нужно преобразовать его в контейнер. Все, что вам нужно сделать в этом сценарии, - это добавить нужные хуки, и вы автоматически подключитесь. В этом сценарии дерево компонентов в ваших инструментах redux также будет значительно чище по сравнению:

Очевидно, это намного легче проверить.

После того, как моя команда осознала эти преимущества, я сделал еще один шаг, предложив новый шаблон проектирования, связанный с организацией этих хуков response-redux в рамках проекта. Используя настраиваемые перехватчики, у нас есть возможность записать эти перехватчики селектора / диспетчеризации только один раз, а затем при необходимости деструктурировать их в наших функциональных компонентах. Рассмотрим эти настраиваемые хуки, созданные в файле с именем user.ts (который соответствует файлу действий пользователя и файлу сокращения пользователя) и помещены в папку хуков в проекте:

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

Как видите, этот новый подключенный компонент намного проще, легче преобразовать в него, менее подвержен ошибкам, а селекторы и диспетчеры намного более модульны. Нам нужно было всего один раз написать селектор и перехватчик диспетчеризации в наших настраиваемых хуках, а затем мы используем перехватчик в нашем компоненте и деструктурируем только тот селектор и перехватчик диспетчеризации, который нам нужен.

TL;DR

Проблемы с подключенными компонентами более высокого порядка (компоненты, заключенные в функцию подключения react-redux):

1) Излишнее переписывание интерфейсов и функций отображения для каждого подключенного компонента

2) Дерево загрязненных компонентов при проверке с помощью инструментов React.

3) Возможность ошибки при импорте подключенного компонента

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

Решение - использовать хуки response-redux useSelector и useDispatch вместе с настраиваемыми хуками.

Больше контента на plainenglish.io