Организация экранов и переиспользуемые компоненты

Наводим порядок в коде: раскладываем экраны и выносим повторяющиеся куски в переиспользуемые компоненты.

Переиспользуемый компонент — выделенный кусок UI (кнопка, карточка), который настраивается через пропсы и используется в разных местах.

Структура папок

Пока приложение маленькое, всё живёт в App.js. Но когда экранов и компонентов становится много, код разносят по папкам. Типичная структура:

src/
  screens/      # экраны: HomeScreen, ProfileScreen
  components/    # переиспользуемые: Button, Card, Avatar
  navigation/    # настройка навигаторов
  api/           # функции запросов к серверу

Принцип простой: экраны — это то, на что можно перейти (целая страница), компоненты — кирпичики, из которых экраны собраны.

Выделяем компонент

Допустим, на нескольких экранах вы рисуете одинаковую карточку. Вместо копирования вынесите её в отдельный компонент и настраивайте пропсами.

import { View, Text, StyleSheet } from "react-native";

function Card({ title, subtitle }) {
  return (
    <View style={styles.card}>
      <Text style={styles.title}>{title}</Text>
      <Text>{subtitle}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  card: { padding: 16, borderRadius: 12, backgroundColor: "#f5f5f5" },
  title: { fontWeight: "bold", fontSize: 16 },
});

export default Card;

Используем где угодно

import Card from "../components/Card";

function HomeScreen() {
  return (
    <Card title="Привет" subtitle="Это переиспользуемая карточка" />
  );
}

Один компонент Card — десятки разных карточек, отличающихся только пропсами. Это и есть сила React-подхода.

Пропсы делают компонент гибким

Через пропсы передают не только текст, но и обработчики, и даже другое содержимое через children.

import { Pressable, Text } from "react-native";

function PrimaryButton({ label, onPress }) {
  return (
    <Pressable onPress={onPress} style={{ padding: 12, backgroundColor: "tomato" }}>
      <Text style={{ color: "white" }}>{label}</Text>
    </Pressable>
  );
}

Признаки, что пора выделить компонент

  • Вы копируете один и тот же JSX в третий раз.
  • Компонент стал слишком большим, в нём трудно разобраться.
  • Кусок UI имеет понятное самостоятельное имя (Avatar, PriceTag).

Имена пропсов — обычный JS

Компонент — это функция, принимающая объект пропсов. Покажем это на чистом JS (запускаемый пример):

function Card(props) {
  return "Карточка: " + props.title + " / " + props.subtitle;
}

console.log(Card({ title: "Кофе", subtitle: "990 ₽" }));
console.log(Card({ title: "Чай", subtitle: "490 ₽" }));

Вывод:

Карточка: Кофе / 990 ₽
Карточка: Чай / 490 ₽

Итог

  • Разносите код по папкам: screens/ для экранов, components/ для кирпичиков.
  • Повторяющийся UI выносите в переиспользуемый компонент.
  • Пропсы (включая children и обработчики) делают компонент гибким.
Проверьте себя
1. Чем экран отличается от компонента?
AНичем, это синонимы
BЭкран — целая страница, на которую переходят; компонент — кирпичик, из которого экран собран
CКомпонент крупнее экрана
DЭкраны нельзя переиспользовать, а компоненты можно только один раз
2. Когда стоит выделить переиспользуемый компонент?
AНикогда, лучше копировать код
BКогда один и тот же JSX повторяется или кусок UI имеет самостоятельное имя
CТолько в последний день проекта
DТолько если так требует Expo
3. Как передать данные в переиспользуемый компонент?
AЧерез глобальные переменные
BЧерез пропсы — аргументы компонента
CЧерез app.json
DЧерез AsyncStorage
Поддержать проект