Инъекционные сервисы в React
Как они реализованы и их сходство с сервисами Angular
React предоставляет фантастический API для создания компонентов. Он легкий и интуитивно понятный, и неспроста стал сенсацией в сообществе разработчиков. С появлением новейших функций API: хуки и контекст / поставщик компоненты стали не только более функциональными, но и более тестируемыми. Позволь мне объяснить.
До сих пор, когда мы хотели, чтобы компонент использовал внешнюю службу, мы просто реализовали его в отдельном модуле, импортировали и использовали его экспортированные методы, например:
Имейте в виду, что это НЕ то, как я на самом деле написал бы свой код в производственной среде, здесь нет обработки ошибок, и оба компонента определены в одном модуле, что я не считаю хорошей практикой, но для демонстрационных целей этого более чем достаточно .
Вышеупомянутые компоненты будут хорошо работать в приложении React, потому что, по сути, они могут достичь того, для чего были реализованы. Однако, если мы захотим провести модульное тестирование этих компонентов, мы столкнемся с проблемой, потому что единственный способ протестировать эти компоненты - использовать тесты e2e или полностью имитировать API выборки. В любом случае решения не в нашу пользу. Либо мы полностью переборщим с тестированием, либо воспользуемся непростым имитирующим решением для ВСЕГО нативного API. Ниже приведен пример:
Если да, то как можно решить эту проблему?
Давайте поучимся у наших коллег по Angular
Я знаю, о чем вы, вероятно, думаете прямо сейчас ... О чем думает этот парень, продвигая шаблоны проектирования Angular, которые совершенно не соответствуют великому React. Во-первых, React не идеален, и ему всегда есть куда доработать. Если бы он уже был идеальным, они бы не продолжали работать над ним в Facebook. Во-вторых, мне нравится React, и я очень в него верю, поэтому я хотел бы улучшить его, используя лучшие практики. Поэтому, прежде чем закрыть вкладку в гневе, продолжайте читать и послушайте, что я хочу сказать :-)
В команде Angular они придумали хитрый подход. Вместо того, чтобы полагаться на жестко запрограммированный импорт, то, что они сделали, они предоставили механизм, который позволил бы нам внедрять наши сервисы до того, как мы инициализируем компонент. При таком подходе мы можем легко смоделировать наши сервисы, потому что с помощью системы внедрения очень легко контролировать, какую реализацию сервисов она будет использовать. Вот как это будет выглядеть на практике:
И теперь, если мы хотим протестировать его, все, что нам нужно сделать, это заменить внедренный сервис, как упоминалось ранее:
Проще говоря, я создал диаграмму, описывающую процесс:
Применение того же шаблона проектирования в React
Теперь, когда мы знакомы с шаблоном проектирования, благодаря Angular, давайте посмотрим, как мы можем добиться того же в React, используя его API. Давайте вкратце вернемся к Контекстному API React:
Контекст можно рассматривать как контейнер, в котором хранится наша служба, он же опора value
, как мы видим в приведенном выше примере. Провайдер определяет, что value
будет содержать контекст, поэтому, когда мы его потребляем, он нам будет предоставлен. Этот API является ключом к имитируемой тестовой единице в React, потому что value
можно заменить на все, что мы захотим. Соответственно, обернем наш auth-service.tsx
:
И мы обновим наш компонент, чтобы использовать новый хук useAuth()
:
Поскольку ловушка useAuth()
использует контекстный API под капотом, ее можно легко заменить другим значением. Все, что нам нужно сделать, это сказать провайдеру, что нужно сохранить другое значение в соответствующем контексте. Как только мы используем контекст, полученное значение должно быть тем же, что было определено провайдером:
Можно спросить: «Означает ли это, что мне нужно обернуть каждую службу контекстным API?», И я отвечу: «Если вы хотите создать приложение React корпоративного качества, то да». В отличие от Angular, React более свободен и не использует этот шаблон проектирования, поэтому вы можете использовать то, что лучше всего подходит для вас.
Прежде чем я закончу эту статью, вот несколько вещей, которые я хотел бы услышать от сообщества и которые, как я полагаю, значительно упростят этот рабочий процесс:
- Имейте стороннюю библиотеку, которая обернет службу контекстным API и упростит ее.
- Имейте правило ESLint, которое заставит использовать инъекционные службы React.
Что вы думаете? Вы согласны с шаблоном проектирования или нет? Собираетесь ли вы стать одним из первых последователей? Напишите свои мысли в разделе комментариев ниже. Также не стесняйтесь подписываться на меня на Medium, или, альтернативно, вы можете подписаться на меня на: