Разрабатываем React-компоненты многократного использования

https://habrahabr.ru/company/efs/blog/347018/
  • Разработка мобильных приложений
  • Программирование
  • ReactJS
  • JavaScript
  • Блог компании Программа «Единая фронтальная система»


В прошлом году мы рассказывали, как устроен фронтенд в Программе «Единая фронтальная система», о библиотеке элементов и нашем подходе к переиспользованию UI компонентов. Сегодня предлагаем сравнить несколько подходов к разработке React-компонентов, спасибо Cory House за отличный материал!



React – это библиотека для создания компонентов. Он позволяет разбить пользовательский интерфейс на составляющие. Вопрос лишь в том, насколько детализированы эти элементы.

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

Получается, что приложение ToDo теперь нужно запускать двумя способами:

1. Самостоятельно;
2. В рамках приложения для выставления счетов.

Как лучше поступить в такой ситуации?



Для запуска React-приложения из разных точек есть три варианта:

1. iframe  — внедрение приложения todo в приложение для выставления счетов через iframe.
2. Многократно используемый компонент приложения  — распространение всего приложения todo через npm.
3. Многократно используемый UI компонент — npm-пакет, включающий только разметку приложения.

Рассмотрим преимущества каждого из этих подходов.

Подход 1: iFrame

Самый простой и очевидный подход — использовать iframe, чтобы поместить приложение ToDo в приложение для выставления счетов. Но тут возникают проблемы:

1. Если два приложения отображают одни и те же данные, есть риск нарушения синхронизации этих данных;
2. Если два приложения используют одни и те же данные, в конечном итоге придется делать лишние обращения к API для получения этих данных;
3. Поведение приложения, помещенного в iframe, нельзя изменить;
4. Когда другая команда выпускает приложение, содержащее ваше приложение внутри iframe, это неминуемо затронет и вас.

Итог: Забудьте! iframe вам не нужен.



Не-не-не!

Подход 2: Многоразовый компонент приложения

Распространение приложения через npm, а не через iframe, позволит избежать проблему № 4 из списка выше, остальные же сохранятся — API, авторизация и поведение. Поэтому я не советую публиковать в npm приложение целиком. Уровень детализации слишком высок, что затрудняет взаимодействие с пользователем.



React-компоненты, которые используются многократно, должны быть детализированными и их должно быть легко компоновать — как детали конструктора LEGO.

Подход 3: Переиспользуемые UI компоненты

Есть более детальный подход, основанный на использовании 2-х составляющих:

1. «Глупые» React-компоненты — только интерфейсы и никаких API-вызовов;
2. API-обертки.

«Глупые» React-компоненты можно легко настраивать, объединять и переиспользовать. При использовании «глупых» компонентов подобным образом вы можете предоставлять необходимые данные или определять, какие API-вызовы должно осуществлять приложение.

Однако, если вы собираетесь объединять несколько «глупых» компонентов, нужно подготовить одинаковый API для нескольких приложений. Вот тут как раз понадобятся API-обертки.

Что такое API-обертки? Это javascript-файлы, содержащие HTTP-запросы к вашему API. Для HTTP-запросов можно использовать, к примеру, библиотеку Axios.

Представьте, что у вас есть пользовательский API. Как сделать пользовательскую API-обертку?

1. Создайте js-файл с публичными функциями, например, getUserById, saveUser
и т.п. При этом каждая функция принимает соответствующие параметры и использует Axios/Fetch для отправки HTTP-запросов к вашему API.
2. Создайте npm-пакета userApi, который будет содержать код вашей обертки.

Пример:

	 /* Данная API-обертка удобна, поскольку она: 
           1. Содержит нашу стандартную конфигурацию Axios.
	   2. Абстрагирует логику для определения baseURL.
	   3. Предоставляет понятный, простой в использовании набор JavaScript-функций для взаимодействия с API. Это делает вызовы API краткими и единообразными. 
	
	*/
	import axios from 'axios';
	
	let api = null;
	
	function getInitializedApi() {
	  if (api) return api; // возвращает api, если он уже инициализирован.
	  return (api = axios.create({
	    baseURL: getBaseUrl(),
	    responseType: 'json',
	    withCredentials: true
	  }));
	}
	
	// Вспомогательные функции
	function getBaseUrl() {
	  // Поместите сюда логику для получения baseURL посредством:
	  // 1. Анализа URL для определения окружения, в котором запущено приложение.
	  // 2. Поиска переменной среды как части процесса сборки.
	}
	
	function get(url) {
	  return getInitializedApi().get(url);
	}
	
	function post(url, data) {
	  return getInitializedApi().post(url, data);
	}
	
	// Публичные функции
	// Обратите внимание, насколько короткой получилась эта часть благодаря общей конфигурации и вспомогательным функциям выше. 
	export function getUserById(id) {
	  return get(`user/${id}`);
	}
	
	export function saveUser(user) {
	  return post(`user/${id}`, {user: user});
	}


Распространенной практикой является публикация React-компонентов и API-оберток в npm в виде приватных пакетов, в качестве альтернативы npm может использоваться Artifactory.

Эти «детали LEGO» обеспечивают основу для быстрого создания новых приложений из переиспользуемых элементов.
Система, составные части которой легко компоновать, предоставляет компоненты, которые можно выбирать и соединять в различных сочетаниях для удовлетворения соответствующих требований пользователя. —  Википедия

В идеале ваш «глупый» переиспользуемый компонент пользовательского интерфейса должен состоять из других переиспользуемых компонентов, также публикуемых в npm.

С многократно используемыми React-компонентами и API-обертками, опубликованными в npm, легко создать что-то реально крутое — почти как из деталей LEGO.

А какой подход используете вы? Приглашаем обсудить в комментариях к статье.
Ещё не оценен