логотип PurpleSchool
логотип PurpleSchool

Гайд по структуре React Native проектов

Автор

Олег Марков

Введение

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

В этом гайде вы узнаете, как лучше организовывать директории и файлы в проектах React Native, на какие принципы стоит полагаться, чтобы структура была понятной и масштабируемой, а также увидите примеры организационных шаблонов, которые используют крупные команды. Я подробно расскажу, какие практики считаются хорошими, какие проблемы могут возникнуть и как их избежать.

Почему структура проекта важна

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

  • Переиспользование компонентов. Хорошая организация упрощает повторное использование кода.
  • Масштабируемость. Чем сложнее ваше приложение, тем важнее порядок — вы легко добавляете новые функции без хаоса.
  • Удобство командной работы. Новым разработчикам проще разобраться, где искать нужные файлы, где добавлять новые модули.
  • Тестирование и сопровождение. Автотесты, исправления, рефакторы — всё эти процессы становятся проще, если структура логична.

Теперь давайте посмотрим, как структурировать проект на практике.

Правильная структура проекта в React Native обеспечивает удобство разработки, масштабируемость и поддержку. Важно знать, как организовывать файлы и папки, использовать модульные компоненты и придерживаться общепринятых соглашений. Также нужно учитывать принципы тестирования и непрерывной интеграции. Если вы хотите детальнее погрузиться в структуру проектов и другие аспекты разработки React Native, — приходите на наш большой курс React Native и Expo Router. На курсе 184 уроков и 11 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

Базовая структура React Native проекта

Когда вы создаёте новый проект с помощью npx react-native init MyApp, вы получаете некую стандартную структуру. Вот как она может выглядеть для чистого проекта:

myApp/
├── __tests__/
├── android/
├── ios/
├── node_modules/
├── src/
├── App.js
├── package.json
├── index.js
├── babel.config.js
└── ...

Краткое описание основных папок

  • android/ и ios/ — отдельные платформенные реализации. Здесь вы найдете нативный код и конфигурацию. Обычно сюда не нужно заходить, если вы работаете только на уровне JS/TS.
  • src/ — место для источников вашего приложения: компонентов, стилей, логики и т.д.
  • App.js — стартовая точка вашего React Native-приложения (основной компонент).
  • index.js — точка входа всего приложения, обычно регистрирует App.js через AppRegistry.

Вы можете часто встретить файлы и папки для настроек (.env, babel.config.js, metro.config.js), а также директорию для тестов (__tests__), документации или сборки (build/, output/).

Оптимальная структура папок внутри src

Всё самое интересное — это организация внутри папки src/. Здесь вы определяете, как будете групировать компоненты, хранилища, бизнес-логику и так далее.

Рассмотрим два основных подхода:

1. Фича-ориентированная структура (Feature-based)

Это наиболее гибкая и масштабируемая схема именно для приложений средней и большой сложности. Здесь каждый модуль (фича) собран в свой "островок", в котором лежат компоненты, стили, утилиты, тесты, связанные только с этой фичей.

src/
├── features/
│   ├── auth/
│   │    ├── components/
│   │    ├── screens/
│   │    ├── api/
│   │    ├── hooks/
│   │    ├── authSlice.js
│   │    ├── styles.js
│   │    └── index.js
│   ├── profile/
│   └── ...
├── shared/
│   ├── components/
│   ├── hooks/
│   ├── utils/
│   ├── constants/
│   └── ...
├── navigation/
├── store/
├── assets/
└── app/
    └── AppNavigator.js

Что включать в features/?

  • components/ — компоненты, которые используются только внутри этой фичи.
  • screens/ — экраны, которые относятся к данной фиче.
  • api/ — функции, отправляющие запросы, связанные только с этой фичей.
  • hooks/ — хуки, специфичные для данной фичи.
  • styles.js — специфические стили для компонентов или экранов фичи.
  • index.js — точка экспорта для всего, что есть в фиче.

Такой подход особенно удобен для крупных приложений: фичу можно легко вынести в отдельный репозиторий или тестить/развивать независимо.

2. Технологическая группа (Layered structure)

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

src/
├── components/
├── screens/
├── navigation/
├── hooks/
├── utils/
├── api/
├── store/
├── assets/
└── constants/

Пояснения

  • components/ — переиспользуемые элементы интерфейса (Button, Header).
  • screens/ — страницы/экраны вашего приложения.
  • navigation/ — навигационные конфиги (например, StackNavigator).
  • api/ — универсальные функции взаимодействия с сервером.
  • store/ — где живет глобальный store приложения (Redux или MobX).

Давайте посмотрим, как можно реализовать такую структуру на практике.

Пример группировки компонентов и экранов

// src/components/Button.js
import React from 'react'
import { TouchableOpacity, Text } from 'react-native'

const Button = ({ onPress, title }) => (
  <TouchableOpacity onPress={onPress} style={{ padding: 10, backgroundColor: '#007BFF' }}>
    <Text style={{ color: '#FFF' }}>{title}</Text>
  </TouchableOpacity>
)

// Кнопка может использоваться в любых экранах
export default Button
// src/screens/LoginScreen.js
import React from 'react'
import { View, Text } from 'react-native'
import Button from '../components/Button'

const LoginScreen = () => (
  <View>
    <Text>Логин</Text>
    <Button title='Войти' onPress={() => { /* логика входа */ }} />
  </View>
)

export default LoginScreen

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

Принципы хорошей организации структуры

Расскажу вам про несколько принципов, которые стоит использовать при планировании структуры:

Не смешивайте ответственность

Пусть в каждой папке лежит только то, что реально относится к этой сущности или фиче. Например, стили для компонентов должны находиться рядом с этими компонентами.

Импортируйте только то, что нужно

Если AppNavigator относится только к навигации, пусть он лежит в папке navigation. Это поможет не засорять пространство общих компонентов.

Минимизируйте вложенность

Чрезмерная вложенность усложняет навигацию — если можно избежать уровня вложенности, лучше избегайте.

Используйте index.js для реэкспорта

Это удобно для ограниченного импорта: когда вы хотите забирать все экспортируемое из директории одной командой. Вот пример:

// src/features/auth/index.js
export { default as LoginScreen } from './screens/LoginScreen'
export { default as AuthAPI } from './api/auth'

Теперь вы можете импортировать LoginScreen так:

import { LoginScreen } from '../features/auth'

Как хранить assets

Любое приложение включает в себя изображения, иконки, шрифты. Для них стоит создать папку assets/ и вложенные поддиректории:

assets/
├── images/
├── icons/
├── fonts/

Вы можете создавать файлы-агрегаторы для большого количества изображений:

// src/assets/images/index.js
export { default as Logo } from './logo.png'
export { default as Bg } from './background.jpg'

И далее:

import { Logo } from '../../assets/images'

Примеры реалистичных структур (шаблоны)

Пример для небольшого приложения

src/
├── components/
├── screens/
├── navigation/
├── api/
├── hooks/
├── utils/
├── assets/
│   ├── images/
│   └── icons/
├── store/
└── constants/

Пример для средне-крупного приложения (фича-ориентированный)

src/
├── features/
│   ├── auth/
│   ├── profile/
│   ├── posts/
│   └── ...
├── shared/
├── navigation/
├── store/
├── assets/

Модулизация и переиспользование

Если вы планируете делить логику на "core" и "feature" блоки, вы можете выносить переиспользуемые компоненты и утилиты в специальную папку, например, shared/ или common/.

// src/shared/components/Loader.js
export default function Loader() { ... }

// src/shared/hooks/useDebounce.js
export function useDebounce() { ... }

Теперь любой компонент из любой фичи может переиспользовать Loader или хуки из shared/.

Использование TypeScript в структуре проекта

Если вы предпочтете TypeScript, его файлы (.ts, .tsx) также группируют по вышеописанным правилам, но дополнительно добавляют папку для типов:

src/
├── types/
│   ├── user.ts
│   ├── post.ts
│   └── ...

Все глобальные типы — здесь, а локальные — рядом с компонентами либо внутри соответствующей фичи.

Совет: Если у вас есть специфичные только для одной фичи/компонента типы, не выносите их в общую папку — это перегружает проект ненужной детализацией.

Работа с конфигами и .env

Практика складывается так: все чувствительные и переменные среды (например, URL API или приватные ключи) кладут в .env, а файл с описанием конфигов (например config.js) — в отдельную папку:

src/
├── config/
│   └── apiConfig.js

Это позволит быстро различать переменные среды и неизменяемые константы проекта.

Отдельно о test-структуре

Допустимо создавать директории __tests__ рядом с тестируемыми файлами или заводить отдельную папку tests/ в корне или в src/. Чаще всего в React Native-приложениях используют первый вариант:

src/
├── features/
│   └── auth/
│        └── __tests__/
│             └── LoginScreen.test.js

Это простое и удобное место — ищите тестовые файлы рядом с реальным функционалом.

Практическая рекомендация — шаги по созданию структуры

Чтобы лучше понять, как подойти к построению структуры, давайте рассмотрим простой чек-лист:

  1. Определите объём приложения: насколько много у вас независимых фич? Простой CRUD — обычно технологическая структура, сложные — фичевая.
  2. Создайте папки для features (или screens/components, если приложение простое).
  3. Добавьте папки для store (Redux/MobX), navigation, assets, hooks, utils.
  4. Решите, где лежат общие стили и темы — удобно использовать отдельную папку theme или shared/styles.
  5. Для типовых ресурсов (изображения, иконки, шрифты) создайте папки assets/images, assets/icons, assets/fonts.
  6. Определите правила именования — лучше CamelCase/FooBar для компонентов и маленькие буквы с дефисами для файлов (button.js, auth-api.js).
  7. Используйте index.js для реэкспорта, чтобы не усложнять импорты.
  8. Держитесь единого стиля импортов — относительные или абсолютные (можно добавить jsconfig.json/tsconfig.json для алиасов).
  9. Все переменные окружения (ключи, host'ы) храните в .env и не коммитьте его в репозиторий.
  10. Для тестов создайте папки вида tests рядом с кодом, который тестируете.

Вот так шаг за шагом вы создадите оптимальную структуру под нужды вашей команды.

Заключение

Грамотная структура проекта React Native — фундамент масштабируемого, легко поддерживаемого и читаемого кода. Ни одна структура не подойдет абсолютно всем приложениям, но если вы выбираете между фича-ориентированной и технологической схемой, опирайтесь на масштаб и команду.

Следуйте простому принципу: организации должно быть достаточно для удобства текущей работы, но не настолько много, чтобы мешать развиваться дальше. Изучайте опыт opensource-сообщества, смотрите на структуру популярных RN-приложений — и не бойтесь рефакторить свою структуру, если почувствуете, что приложение "переросло" текущую схему.

Создание правильной структуры сильно упрощает разработку. Для разработки полноценного приложения необходимо также уметь управлять состоянием, обеспечивать навигацию и работать с API. На нашем курсе React Native и Expo Router вы найдете все необходимые знания для создания профессиональных React Native приложений. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в мир React Native прямо сегодня.

Частозадаваемые технические вопросы по теме статьи и ответы на них

В: Как добавить абсолютные пути (алиасы) для импорта файлов в React Native?

A:
Используйте файл jsconfig.json (для JS) или tsconfig.json (для TypeScript) в корне проекта.
Пример для JS:

{
  "compilerOptions": {
    "baseUrl": "src",
    "paths": {
      "@components/*": ["components/*"]
    }
  }
}

После этого импорт будет выглядеть так:

import Button from '@components/Button'

Для поддержки алиасов в Babel добавьте в .babelrc или babel.config.js плагин babel-plugin-module-resolver и настройте аналогично.

В: Как правильно структурировать стили в большом проекте?

A:
Создайте отдельную папку styles/ в src/ для глобальных тем и вынесите локальные стили рядом с компонентами, которые их используют, например, MyButton/styles.js. Чаще всего глобальные стили оформляют через Context API или специализированные библиотеки типа styled-components.

В: Как структурировать папку для кастомных хуков?

A:
Лучше всего создать папку hooks/ в корне src/, а если хук используется только в конкретной фиче — располагайте его внутри соответствующей папки фичи. Следуйте такому паттерну для понятности.

В: Где хранить глобальные прокидываемые константы (например, цвета темы)?

A:
Создайте папку constants/ или theme/ внутри src/ и определите там файлы вроде colors.js, fonts.js, sizes.js. Используйте эти константы во всех стилях через импорт.

В: Как организовать структуру для поддержки масштабирования команды?

A:
Используйте фича-ориентированную структуру: каждый разработчик работает с определенной фичей (папкой), внутри которой лежит всё необходимое. Вынесите общие утилиты и компоненты в shared/ — так уменьшите пересечения между разработчиками и ускорите ревью.

Стрелочка влевоЗапуск приложения React Native на устройстве или эмулятореСоздание чат-приложения на React NativeСтрелочка вправо

Постройте личный план изучения React-native до уровня Middle — бесплатно!

React-native — часть карты развития Mobile

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по React-native

Работа со ScrollView в React NativeРабота с видео в React NativeКак реализовать аудиоплеер на React NativeНастройка и использование input и textinput в React NativeИнтеграция видео плеера в приложение на React NativeИспользование выпадающих списков в React NativeСоздание и настройка native module на React NativeКак создать модальные окна в React NativeРабота с изображениями в React NativeОтображение списков данных в React NativeГайд по файловой системе в React NativeИнтеграция камеры в приложение на React NativeСоздание интерактивных кнопок в React Native
Как использовать векторные иконки в React Native5 популярных библиотек UI компонентов React NativeСоздание и использование tabs в React NativeРуководство по стилизации компонентов в React NativeОптимизация переходов между экранами в React NativeАдаптация safe area context на React NativeОбзор библиотек для навигации в React NativeСоздание сложных анимаций (reanimated) на React NativeИспользование библиотеки стилей Paper в React NativeРуководство по navigation в React NativeОптимизация отображения списков в React NativeКак реализовать linking на React NativeГайд по UI-китам для React NativeГде искать elements для приложения на React NativeРабота с цветами в React Native
Открыть базу знаний

Лучшие курсы по теме

изображение курса

React Native и Expo Router

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Основы JavaScript

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий