Найти в Дзене
Nuances of programming

Совместное использование кода в приложениях React и React Native

Источник: Nuances of Programming React и React Native помогают сблизить веб- и мобильную разработку, улучшая опыт как пользователей, так и разработчиков. Некоторые продвинутые команды уже создают полноценную кроссплатформенную систему проектирования с помощью React и React Native (видеоурок). Хотя React и RN требуют различной реализации (браузеры и мобильные устройства не одинаковы), типы приложений и компонентов зачастую имеют общий код, бизнес-логику, хуки, реквизиты и даже дизайн-токены. В данном руководстве будет показано, как превратить общие элементы в общие зависимости для приложений React и RN. Эти компоненты версионируются, так что впоследствии их можно обновлять и управлять ими на разных платформах. Весь описанный ниже процесс будет упрощен благодаря использованию проекта Bit с открытым исходным кодом. Здесь можно найти (и использовать) все компоненты из этого руководства. Итак, погрузимся в процесс. 1. Два компонента: React и React Native Нам предстоит работа с двумя аккорде
Оглавление

Источник: Nuances of Programming

React и React Native помогают сблизить веб- и мобильную разработку, улучшая опыт как пользователей, так и разработчиков.

Некоторые продвинутые команды уже создают полноценную кроссплатформенную систему проектирования с помощью React и React Native (видеоурок).

Аккордеон React-Native, который мы создадим; для веб-приложения у нас будет также аккордеон React
Аккордеон React-Native, который мы создадим; для веб-приложения у нас будет также аккордеон React

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

В данном руководстве будет показано, как превратить общие элементы в общие зависимости для приложений React и RN. Эти компоненты версионируются, так что впоследствии их можно обновлять и управлять ими на разных платформах.

Весь описанный ниже процесс будет упрощен благодаря использованию проекта Bit с открытым исходным кодом.

Здесь можно найти (и использовать) все компоненты из этого руководства.

Итак, погрузимся в процесс.

1. Два компонента: React и React Native

Нам предстоит работа с двумя аккордеонами  —  одним для React, другим для React Native.

Вот компонент аккордеона React.

-3

Изучите и установите/откройте его, чтобы протестировать локально или отредактировать.

Другой компонент  —  React Native.

-4

Уделите пару секунд изучению графа “зависимости” каждого компонента. Согласитесь, у них много общих зависимостей.

Общие зависимости компонентов React и React Native
Общие зависимости компонентов React и React Native

2. Превращение общего кода в общие зависимости

Наша задача  —  сделать так, чтобы каждый аккордеон содержал минимум платформенно-ориентированного кода (поскольку API у них разные), и передать все общие части.

С помощью Bit можно что угодно превратить в компоненты, в том числе зависимости компонентов аккордеонов. Поскольку нам нужно максимально увеличить объем кода вне платформенно-ориентированных реализаций, хуки, типы, темы и дизайн-токены будут частью различных компонентов.

Вот зависимости компонентов, которые нужно создать и скомпоновать с аккордеонами React и React Native (можно найти их все здесь):

share-react-react-native --> scope
├── api --> namespace
│ ├── accordion --> component
│ └── accordion-items --> component
├── design-tokens --> namespace
│ ├── base-tokens --> component
│ ├── react-tokens --> component
│ └── rnative-tokens --> component
├── base-ui --> namespace
│ ├── hooks --> namespace
│ │ ├── use-open --> component
│ │ └── use-select --> component
│ ├── react --> namespace
│ │ └── accordion --> component
│ └── react-native --> namespace
│ └── accordion --> component
└── theme --> namespace
├── web --> component
└── mobile --> component

3. Добавление зависимостей в платформенно-ориентированные компоненты

Между React и React Native есть различия. Например, они не допускают применения одинаковых свойств и типов стилей. Если все размерности в React Native не имеют единиц измерения, то в React можно использовать px, rem, em и т.д.

Для выполнения нашей задачи понадобятся базовый объект с наиболее общими значениями и платформенно-ориентированные компоненты с дополнительными свойствами.

Воспользуемся полезным шаблоном создания контекста и хука для внедрения токенов в компоненты. Чтобы заставить их работать с React и React Native, прибегнем к хитрости. Она заключается в том, что у нас будет три вида токенов.

  • Базовый токен  —  общий для обоих:
export interface BaseTokensProps {
primaryColor: string;
secondaryColor: string;
borderColor: string;
borderStyle: "solid" | "dotted" | "dashed" | undefined;
}

export const baseTokens: BaseTokensProps = {
primaryColor: "red",
secondaryColor: "blue",
borderColor: "green",
borderStyle: "solid",
};

  • Токен, дополняющий базовый для использования с React:
import { baseTokens } from "@learnbit-react/web-mobile-design-system.design-tokens.base-tokens";
import type { BaseTokensProps } from "@learnbit-react/web-mobile-design-system.design-tokens.base-tokens";
export interface ReactTokensProps extends BaseTokensProps {
spacing: string;
fontSize: string;
borderWidth: string;
}
export const reactTokens: ReactTokensProps = {
...baseTokens,
spacing: "15px",
fontSize: "18px",
borderWidth: "3px",
};
  • Токен, дополняющий базовый для использования с React Native:
import { baseTokens } from "@learnbit-react/web-mobile-design-system.design-tokens.base-tokens";
import type { BaseTokensProps } from "@learnbit-react/web-mobile-design-system.design-tokens.base-tokens";
export interface RNativeTokensProps extends BaseTokensProps {
spacing: number;
fontSize: number;
borderWidth: number;
}
export const rNativeTokens: RNativeTokensProps = {
...baseTokens,
primaryColor: "purple",
secondaryColor: "gray",
spacing: 10,
fontSize: 12,
borderWidth: 3,
};
Если в вашей среде разработки выполняется автозаполнение местоположения посредством относительного импорта, можете быстро исправить это, выполнив команду bit link — rewire.

4. Предоставление тем для React и React Native

В Bit тема может быть и компонентом, что позволяет легко составлять зависимости для дизайн-токенов и тем.

Для нашей темы используем уже имеющийся компонент, который создает тему из объекта. Для этого нужно установить его в рабочее пространство:

$ bit install @teambit/base-react.theme.theme-provider

Нам понадобится объект tan со свойствами темы. Вызовем функцию createTheme, указав ее в качестве аргумента. Результатом будет объект с хуком для использования этих значений и компонент, который осуществляет ввод с помощью React Context.

import { createTheme } from "@teambit/base-react.theme.theme-provider";
import { reactTokens } from "@learnbit-react/web-mobile-design-system.design-tokens.react-tokens";
import type { ReactTokensProps } from "@learnbit-react/web-mobile-design-system.design-tokens.react-tokens";
const theme = createTheme<ReactTokensProps>({
theme: reactTokens,
});
const { useTheme, ThemeProvider } = theme;
export { useTheme, ThemeProvider };
  • А вот и тема для React Native. Передадим опцию withoutCssVars: true, чтобы избежать необходимости рендеринга <div>.
import { createTheme } from "@teambit/base-react.theme.theme-provider";
import { rNativeTokens } from "@learnbit-react/web-mobile-design-system.design-tokens.rnative-tokens";
import type { RNativeTokensProps } from "@learnbit-react/web-mobile-design-system.design-tokens.rnative-tokens";
const theme = createTheme<RNativeTokensProps>({
theme: rNativeTokens,
withoutCssVars: true,
});
const { useTheme, ThemeProvider } = theme;
export { useTheme, ThemeProvider };

Предоставим темы аккордеонам. Теперь это просто сделать: можно импортировать компоненты-темы.

Оба аккордеона будут иметь одинаковый каркас, где мы используем хуки и получаем в качестве возврата соответствующий список, как показано в этом фрагменте:

import { useTheme } from '@learnbit-react/web-mobile-design-system.theme.web // or .mobile in the react-native one!
import { useOpen } from '@learnbit-react/web-mobile-design-system.hooks.use-open';
import { useSelect } from '@learnbit-react/web-mobile-design-system.hooks.use-select';
import type { AccordionProps } from '@learnbit-react/web-mobile-design-system.api.accordion';
const GenericAccordionTemplate = ({ elementList } : AccordionProps) => {
const { isOpen, toggleOpen } = useOpen();
const { selectedId, setSelection } = useSelect();
const {someValueToken, someValueToken} = useTheme();
return <div_or_View style={{someProp: someValueToken}}>My styled element<div_or_View/>;
};
Обратите внимание, что аккордеоны не используют один и тот же хук useTheme. Каждый из них использует свой хук в соответствии с заданными типами стилей.

5. Создание веб- и мобильного приложений с общими зависимостями

Наконец пришло время создать веб- и мобильное приложения с использованием новых компонентов и общих зависимостей. В компонуемых приложениях (т.е. с Bit) всегда есть возможность добавить компонент и развернуть его. Поскольку здесь все является компонентом, можно добавить компонент для развертывания в Netlify или создать/добавить любые аналогичные компоненты для развертывания в любом месте. Подробнее здесь.

Веб-приложение React

Вот конечный резульат развертывания в Netlify. Посмотрим, как это сделать.

Создадим компонент приложения и установим Netlify.

$ bit create react-app apps/react/accordion — scope learnbit-react.web-mobile-design-system
bit install react-router-dom
bit use learnbit-react.web-mobile-design-system/apps/react/accordion
bit install @teambit/cloud-providers.deployers.netlify

Теперь добавим аккордеон в код приложения.

import React from "react";
import { Routes, Route } from "react-router-dom";
import { Accordion } from "@learnbit-react/web-mobile-design-system.base-ui.react.accordion";
import { Item } from "@learnbit-react/web-mobile-design-system.api.accordion"; export function AccordionApp() {
return (
<>
{/* header component */}
<Routes>
<Route
path="/"
element={
<Accordion
elementList={[
new Item("Asia", "01").toObject(),
new Item("Africa", "02").toObject(),
new Item("North America", "03").toObject(),
new Item("South America", "04").toObject(),
new Item("Antarctica", "05").toObject(),
new Item("Australia / Oceania", "06").toObject(),
new Item("Europe", "07").toObject(),
]}
/>
}
/>
<Route path="/about">{/* about page component */}</Route>
</Routes>
{/* footer component */}
</>
);
}

Путем настройки приложения в accordion.react-app.ts и запуска bit tag, получим его снапшот и развернем его:

bit tag apps/react/accordion -m “First deploy”

Наконец оно развернуто!

Использование компонента React Native в Expo

expo init my-new-project
cd my-new-project

yarn install @learnbit-react/web-mobile-design-system.base-ui.react-native.accordion @learnbit-react/web-mobile-design-system.api.accordion

Добавим компонент в файл app.js:

import {Accordion} from '@learnbit-react/web-mobile-design-system.base-ui.react-native.accordion';
import { Item } from '@learnbit-react/web-mobile-design-system.api.accordion';
import {(StyleSheet, View)} from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<Accordion
elementList={[
new Item('Asia', '01').toObject(),
new Item('Africa', '02').toObject(),
new Item('North America', '03').toObject(),
new Item('South America', '04').toObject(),
new Item('Antarctica', '05').toObject(),
new Item('Australia / Oceania', '06').toObject(),
new Item('Europe', '07').toObject(),
]}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'flex-start',
marginTop: 50,
},
});

Вот исходный код на GitHub.

Вывод

Браузеры и мобильные устройства отличаются друг от друга, и вы не можете использовать все то общее, что у них есть. При этом у них могут быть общими множество элементов кода и дизайна. Превращение этих элементов в компонуемые зависимости позволит эффективно использовать их совместно, вводя в состав компонентов и приложений React и React Native. Вы сможете версионировать и управлять обновлениями между ними, чтобы сохранить единство кодовой базы и UI/UX на разных платформах.

Читайте также:

Читайте нас в Telegram, VK

Перевод статьи Jonathan Saring: Sharing Code Between React and React Native