Статьи

Начало работы с React Native

С ростом популярности смартфонов разработчики ищут решения для создания мобильных приложений. Для разработчиков с веб-опытом такие платформы, как Cordova и Ionic, React Native, NativeScript и Flutter, позволяют нам создавать мобильные приложения с языками, с которыми мы уже знакомы: HTML, XML, CSS и JavaScript.

В этом руководстве мы подробнее рассмотрим React Native. Вы изучите абсолютные основы начала работы с ним. В частности, мы рассмотрим следующее:

  • что такое React Native
  • что такое Экспо
  • как настроить среду разработки React Native
  • как создать приложение с React Native

Хотите узнать React Native с нуля? Эта статья является выдержкой из нашей Премиум библиотеки. Получите полную коллекцию книг React Native, охватывающую основы, проекты, советы и инструменты и многое другое с SitePoint Premium. Присоединяйтесь сейчас всего за $ 9 / месяц .

Предпосылки

В этом руководстве предполагается, что вы пришли из веб-разработки. Минимальное требование, чтобы вы могли уверенно следовать этому руководству, — это знать HTML, CSS и JavaScript. Вы также должны знать, как установить программное обеспечение в вашей операционной системе и работать с командной строкой. Мы также будем использовать некоторый синтаксис ES6, поэтому было бы полезно, если вы также знаете базовый синтаксис ES6. Знание React полезно, но не обязательно.

Что такое React Native?

React Native — это платформа для создания приложений, которые работают как на Android, так и на iOS. Это позволяет вам создавать настоящие нативные приложения, используя JavaScript и React. Это отличается от фреймворков, таких как Cordova, где вы используете HTML для создания пользовательского интерфейса, и он будет отображаться только во встроенном мобильном браузере устройства (WebView). React Native имеет встроенные компоненты, которые компилируются в нативные компоненты пользовательского интерфейса, а ваш код JavaScript выполняется через виртуальную машину. Это делает React Native более производительным, чем Cordova.

Еще одним преимуществом React Native является его способность получать доступ к собственным функциям устройства. Существует множество плагинов, которые можно использовать для доступа к собственным функциям устройства, таким как камера и различные датчики устройства . Если вам нужна специфичная для платформы функция, которая еще не была реализована, вы также можете создавать свои собственные нативные модули — хотя это потребует от вас значительных знаний о нативной платформе, которую вы хотите поддерживать (Java или Kotlin) для Android и Objective C или Swift для iOS).

Если вы приходите сюда и вы новичок в React, вам может быть интересно, что это такое. React — это библиотека JavaScript для Интернета для создания пользовательских интерфейсов. Если вы знакомы с MVC, это в основном View в MVC. Основная цель React — позволить разработчикам создавать повторно используемые компоненты пользовательского интерфейса. Примеры этих компонентов включают кнопки, ползунки и карты. React Native взял идею создания повторно используемых компонентов пользовательского интерфейса и включил их в разработку мобильных приложений.

Что такое Экспо?

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

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

Но это именно так, как Экспо изначально продается. На самом деле, это гораздо больше, чем это. На самом деле Expo — это платформа, которая предоставляет вам доступ к инструментам, библиотекам и сервисам для быстрого создания приложений для Android и iOS с React Native. Expo поставляется с SDK, который включает в себя большинство API-интерфейсов, которые вы можете запросить в платформе разработки мобильных приложений:

Это лишь немногие из API, к которым вы получаете доступ из коробки, если вы начинаете создавать приложения React Native с Expo. Конечно, эти API доступны и для вас через собственные модули, если вы разрабатываете свое приложение с использованием стандартной установки React Native.

Обычная Реакция Родной или Экспо?

Вопрос в том, какой из них выбрать — React Native или Expo? Там действительно нет правильного или неправильного ответа. Все зависит от контекста и ваших потребностей на данный момент. Но я думаю, можно с уверенностью предположить, что вы читаете этот учебник, потому что вы хотите быстро начать работу с React Native. Поэтому я рекомендую вам начать с Экспо. Это быстро, просто и легко настроить. Вы можете погрузиться в работу с кодом React Native и почувствовать, что он может предложить, всего за пару часов.

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

Примечание. Такие проекты, как unimodules, начинают сокращать разрыв между стандартными проектами React Native и проектами Expo, поскольку это позволяет разработчикам создавать собственные модули, которые работают как для React Native, так и для ExpoKit.

Настройка среды разработки React Native

В этом разделе мы настроим среду разработки React Native для всех трех основных платформ: Windows, Linux и macOS. Мы также расскажем, как настроить симуляторы для Android и iOS. Наконец, мы расскажем, как настроить Expo. Если вы просто хотите быстро начать работу, я рекомендую вам прокрутить вниз до раздела «Настройка Экспо».

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

  1. установить JDK
  2. установить Android Studio или Xcode
  3. установить сторож
  4. обновить переменную среды
  5. установить эмулятор
  6. установить узел
  7. установить React Native CLI

Вы можете перейти к разделу, соответствующему вашей операционной системе. Некоторые шаги — например, настройка Android Studio — в основном одинаковы для каждой операционной системы, поэтому я поместил их в отдельный раздел:

  • настройка в Windows
  • настройка на Linux
  • настройка на macOS
  • настройка Android Studio
  • установить узел
  • создание Экспо
  • настройка эмуляторов
  • установить React Native CLI
  • устранение распространенных ошибок

Настройка в Windows

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

Установить шоколад

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

@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin" 

Теперь мы можем установить другие нужные нам инструменты, просто используя Chocolatey.

Установить Python

Python поставляется с инструментами командной строки, необходимыми для React Native:

 choco install -y python 2 

Установить JDK

JDK позволяет вашему компьютеру понимать и выполнять код Java. Обязательно установите JDK версии 8, поскольку это требуется для React Native:

 choco install jdk8 

Установить NVM

У узла есть установщик для Windows . Лучше использовать NVM для Windows, так как это позволит вам установить несколько версий Node, чтобы вы могли тестировать новые версии или использовать другую версию в зависимости от проекта, над которым вы сейчас работаете. Для этого вы можете использовать NVM для Windows. Скачайте nvm-setup.zip , распакуйте его и выполните nvm-setup.exe чтобы установить его.

Установить сторож

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

Обновите переменные среды

Это последний шаг в настройке React Native в Windows. Здесь мы обновляем переменные среды, чтобы операционная система знала обо всех инструментах, необходимых для React Native. Выполните следующие действия непосредственно перед установкой React Native CLI.

  1. Перейдите в Панель управленияСистема и безопасностьСистема . Оказавшись там, нажмите меню расширенных настроек системы слева.

    Расширенные настройки системы Windows

  2. Это откроет окно свойств системы. Нажмите кнопку Переменные среды :

    Свойства системы

  3. В разделе « Пользовательские переменные » выделите переменную Path и нажмите кнопку редактирования .

  4. На экране редактирования нажмите кнопку « Создать» и введите путь к Android SDK и инструментам платформы. Для меня это на C:\users\myUsername\AppData\Local\Android\Sdk и C:\users\myUsername\AppData\Local\Android\Sdk\platform-tools . Обратите внимание, что здесь вы также можете добавить путь к JDK, если он еще не добавлен:

    добавить путь

Настройка в Linux

В этом разделе показано, как установить и настроить инструменты, необходимые для разработки приложений React Native в Linux. Я специально использовал Ubuntu 18.04 для тестирования, но вы должны иметь возможность переводить команды в дистрибутив Linux, который вы используете.

Установите необходимые инструменты

Первым шагом является установка следующих инструментов. Первая строка устанавливает инструменты, необходимые для Node, а вторая строка требуется для Watchman, который мы также установим позже:

 sudo apt-get install build-essential libssl-dev curl sudo apt-get install git autoconf automake python-dev 

Установить NVM

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

 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash source ~/.profile 

Примечание. Обязательно проверьте последнюю версию на странице выпусков, чтобы убедиться, что устанавливаемая версия NVM обновлена.

Установить JDK

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

 sudo apt-get install openjdk-8-jre 

Установить сторож

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

 git clone https://github.com/facebook/watchman.git cd watchman git checkout v4.9.0 ./autogen.sh ./configure make sudo make install 

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

  CXX scm/watchman-Mercurial.o scm/Mercurial.cpp: In constructor 'watchman::Mercurial::infoCache::infoCache(std::__cxx11::string)': scm/Mercurial.cpp:16:40: error: 'void* memset(void*, int, size_t)' clearing an object of non-trivial type 'struct watchman::FileInformation'; use assignment or value-initialization instead [-Werror=class-memaccess] memset(&dirstate, 0, sizeof(dirstate)); ^ In file included from scm/Mercurial.h:10, from scm/Mercurial.cpp:3: ./FileInformation.h:18:8: note: 'struct watchman::FileInformation' declared here struct FileInformation { ^~~~~~~~~~~~~~~ cc1plus: all warnings being treated as errors make: *** [Makefile:4446: scm/watchman-Mercurial.o] Error 1 

Попробуйте вместо этого следующую команду:

 ./configure --without-python --without-pcre --enable-lenient 

Обновите переменные среды

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

Чтобы обновить переменные среды, откройте файл .bash_profile :

 sudo nano ~/.bash_profile 

Добавьте в начале следующее, затем сохраните файл:

 export ANDROID_HOME=$HOME/Android/Sdk export PATH=$PATH:$ANDROID_HOME/emulator export PATH=$PATH:$ANDROID_HOME/tools export PATH=$PATH:$ANDROID_HOME/tools/bin export PATH=$PATH:$ANDROID_HOME/platform-tools 

Обратите внимание, что путь выше предполагает, что Android SDK установлен в домашнем каталоге вашего пользователя:

 echo $HOME 

Настройка на macOS

Наличие Mac позволяет разрабатывать приложения для Android и iOS с помощью React Native. В этом разделе я покажу, как вы можете настроить среду разработки для Android и iOS.

Установка обязательных инструментов

Поскольку macOS уже поставляется с Ruby и cURL по умолчанию, вам нужно установить только один инструмент Homebrew , менеджер пакетов для macOS:

 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 

Если он уже установлен, просто обновите его следующим образом:

 brew update 

Для iOS требуется следующее:

  • Последняя версия Xcode : устанавливает инструменты, необходимые для компиляции приложений iOS
  • Сторож : для просмотра изменений файлов
  • NVM : для установки Node

Установить JDK

Установите JDK версии 8 для macOS, как того требует React Native:

 brew tap AdoptOpenJDK/openjdk brew cask install adoptopenjdk8 

Установить сторож

Watchman ускоряет процесс компиляции вашего исходного кода. Установка необходима как для Android, так и для iOS:

 brew install watchman 

Установить NVM

NVM позволяет вам установить несколько версий Node для тестирования:

 brew install nvm echo "source $(brew — prefix nvm)/nvm.sh" >> .bash_profile 

Обновление переменных среды

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

Чтобы обновить его, откройте файл .bash_profile :

 sudo nano ~/.bash_profile 

Затем добавьте путь к Android SDK и инструментам платформы:

 export ANDROID_HOME=/Users/$USER/Library/Android/sdk export PATH=${PATH}:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator 

Настройка Android Studio

Android Studio — это самый простой способ установить инструменты, необходимые для Android (Android SDK, Android Emulator), поэтому этот метод я обычно рекомендую новичкам. Вы можете скачать установщик для вашей конкретной платформы здесь .

В Windows и macOS имеется мастер настройки, который вы можете просто запустить, нажимая кнопку « Далее» до завершения установки. Обязательно выберите здесь файл .dmg для macOS или файл .exe для Windows, если кнопка загрузки по умолчанию загружает что-то другое. Вы можете использовать следующие скриншоты в качестве основы для вашей установки.

Если вы работаете в Linux, прежде чем приступить к установке Android Studio, выполните следующие действия:

  1. Загрузите и распакуйте файл .tar.gz :

     tar -xzvf android-studio-ide-183.5522156-linux.tar.gz 
  2. Перейдите к извлеченному каталогу и перейдите в каталог bin .

  3. Выполнить studio.sh . Это открывает установщик для Android Studio:

     ./studio.sh 

Мастер установки сначала приветствует вас следующим экраном:

Настройка Android-студии

Просто нажмите Next, пока не увидите экран ниже. Android SDK и последняя версия Android API проверяются по умолчанию. Вы также можете проверить виртуальное устройство Android, если хотите. Это устанавливает эмулятор Android по умолчанию для тестирования ваших приложений. Но я обычно рекомендую вместо этого использовать Genymotion , поскольку он поставляется с лучшими инструментами для тестирования различных функций устройства:

API-интерфейсы Android Studio

Как только он установит все, он покажет следующее. Просто нажмите « Готово», чтобы закрыть мастер установки:

Android Studio завершила установку

Следующим шагом является открытие Android Studio для настройки платформы и инструментов SDK:

Менеджер SDK

Примечание. Если вы ранее установили Android Studio, возможно, уже открыт уже существующий проект. В этом случае вы можете запустить SDK Manager из главного меню ToolsSDK Manager . Затем проверьте Показать детали пакета в правом нижнем углу. Таким образом, вы можете выбрать только подкомпоненты, а не устанавливать все это.

На вкладке Платформы SDK убедитесь, что проверено следующее:

  • Android 9.0 (пирог)
    • Платформа Android SDK 28
    • API Google Системный образ Intel x86 Atom_64 или Системный образ Intel x86 Atom_64

SDK менеджер 2

На вкладке Инструменты SDK снова проверьте Показать подробности пакета и убедитесь, что проверено следующее:

  • Android SDK Build-Tools 29
    • 28.0.3
  • Android SDK Платформа-Инструменты
  • Инструменты Android SDK
  • Репозиторий поддержки Android
  • Google Repository

Проверьте следующее, если вы решили установить эмулятор Android:

  • Intel x86 Emulator Accelerator (установщик HAXM)

Это оптимизирует производительность эмулятора.

Установить узел

Выполните следующие команды, чтобы установить конкретную версию Node и установить ее по умолчанию:

 nvm install 11.2.0 nvm alias default 11.2.0 

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

 node --version npm --version 

Вот как будет выглядеть вывод:

версия узла и npm

Настройка Экспо

В этом разделе мы настроим Expo, альтернативный способ разработки приложений React Native. В этом разделе предполагается, что у вас уже установлены Node и Watchman.

Чтобы настроить Expo, все, что вам нужно сделать, это установить инструмент командной строки через npm:

 npm install -g expo-cli 

Это действительно все, что нужно сделать! Следующим шагом является загрузка клиентского приложения Expo для Android или iOS . Обратите внимание, что это единственный способ запускать приложения Expo, пока вы еще в разработке. Позже вы можете создать автономную версию .

Отсюда вы можете перейти к разделу Hello World App, если вы планируете запускать приложения на своем устройстве, или к разделу Настройка эмуляторов, если вы хотите запустить его на эмуляторе Android или iOS Simulator.

Настройка эмуляторов

Эмуляторы позволяют вам тестировать приложения, которые вы разрабатываете, прямо с вашего компьютера.

Примечание: эмуляторы требуют, чтобы на вашей машине было не менее 4 ГБ ОЗУ В противном случае они действительно замедлят работу вашего компьютера до такой степени, что вы ничего не сделаете из-за ожидания компиляции или загрузки.

iOS Симулятор

Xcode уже предустановлен с симуляторами iOS, поэтому все, что вам нужно сделать, это запустить его, прежде чем запускать приложения. Чтобы запустить симулятор iOS из командной строки, вы должны сначала перечислить доступные симуляторы:

 xcrun simctl list 

Список симуляторов iOS

Запишите UUID устройства, которое вы хотите запустить, и замените его значением UUID команды ниже:

  open -a Simulator --args -CurrentDeviceUDID "UUID" 

Genymotion

Как упоминалось ранее, я рекомендую Genymotion в качестве эмулятора для Android, поскольку он имеет больше возможностей устройства, которые вы можете протестировать — например, при тестировании приложений, использующих GPS. Genymotion позволяет выбрать конкретное место через интерфейс карты:

Genymotion GPS

Чтобы установить Genymotion, сначала необходимо загрузить и установить VirtualBox . После этого зарегистрируйте учетную запись Genymotion , войдите в систему и загрузите установщик . Windows и macOS поставляются с соответствующим установщиком. Но для Linux вы должны скачать установщик и сделать его исполняемым:

 chmod +x genymotion-<version>_<arch>.bin 

После этого вы можете запустить установщик:

 ./genymotion-<version>_<arch>.bin 

После завершения установки вы сможете найти его на своей панели запуска.

Эмулятор Android

Несмотря на то, что Genymotion — это первое, что я рекомендую, я считаю, что Android Emulator также имеет свои достоинства. Например, он загружается быстрее и в целом чувствует себя быстрее. Я рекомендую его, если ваша машина имеет более низкие характеристики или если вам не нужны дополнительные функции Genymotion.

Когда вы запускаете Android Studio, вы можете выбрать AVD Manager из опций конфигурации (или ИнструментыAVD Manager, если у вас есть открытый проект).

Нажмите кнопку « Создать виртуальное устройство» в открывшемся окне. Затем вам будет предложено выбрать устройство, которое вы хотите установить:

выберите виртуальное устройство

Вы можете выбрать любой, какой захотите, но в идеале вы хотите, чтобы в него уже был включен Play Store. Это будет особенно полезно, если ваше приложение интегрируется с Google Sign in или другими приложениями, поскольку это позволит вам легко устанавливать эти приложения.

Далее вам будет предложено загрузить версию Android, которую вы хотите установить на устройство. Просто выберите последнюю версию Android, поддерживаемую React Native. На момент написания этого руководства это Android Pie. Обратите внимание, что это также та же версия, которую мы установили для платформы Android SDK ранее:

образ системы

После установки нажмите « Готово», чтобы закрыть текущее окно, затем нажмите « Далее», как только вы увидите этот экран:

Android установлен

Нажмите Finish на следующем экране, чтобы создать эмулятор. Затем он будет указан в диспетчере виртуальных устройств Android. Нажмите на кнопку воспроизведения рядом с эмулятором, чтобы запустить его.

Установите React Native CLI

Последний шаг — установить React Native CLI. Это инструмент командной строки, который позволяет вам загрузить новый проект React Native, связать собственные зависимости и запустить приложение на устройстве или эмуляторе:

 npm install -g react-native-cli 

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

 react-native init HelloWorldApp cd HelloWorldApp react-native run-android react-native run-ios 

Вот как приложение будет выглядеть по умолчанию:

экран React Native по умолчанию

Теперь у вас есть полностью функциональная среда разработки React Native.

Устранение распространенных ошибок

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

Не удалось найти tools.jar

Вы можете получить следующую ошибку:

 Could not find tools.jar. Please check that /usr/lib/jvm/java-8-openjdk-amd64 contains a valid JDK installation 

Это означает, что система не распознает вашу установку JDK. Решение состоит в том, чтобы повторно установить это:

 sudo apt-get install openjdk-8-jdk 

Расположение SDK не найдено

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

 FAILURE: Build failed with an exception. * What went wrong: A problem occurred configuring project ':app'. > SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable. 

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

 echo $PATH 

Он должен показать следующий путь:

 Android/sdk/tools Android/sdk/tools/bin Android/sdk/platform-tools 

Если нет, то вам нужно отредактировать файл .bashrc или .bash_profile чтобы добавить отсутствующий путь. Конфигурация ниже добавляет путь к инструментам платформы:

 sudo nano ~/.bash_profile export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools 

Невозможно найти служебные «инструменты»

Если вы разрабатываете для iOS, вы можете столкнуться со следующей ошибкой при попытке запустить приложение:

 Found Xcode project TestProject.xcodeproj xcrun: error: unable to find utility "instruments", not a developer tool or in PATH 

Проблема в том, что инструменты командной строки Xcode еще не установлены. Вы можете установить их с помощью следующей команды:

 xcode-select --install 

Приложение «Hello World»

Теперь, когда ваша среда разработки настроена, вы можете приступить к созданию обязательного приложения «hello world». Приложение, которое вы собираетесь создать, является поисковым приложением Pokemon. Это позволит пользователю вводить имя покемона и просматривать его детали.

Вот как будет выглядеть окончательный результат:

Pokemon Search App

Вы можете найти исходный код этого репозитория GitHub .

Начальная загрузка приложения

На вашем терминале выполните следующую команду, чтобы создать новый проект React Native:

 react-native init RNPokeSearch 

Для тех из вас, кто решил вместо этого использовать Expo, вот эквивалентная команда для запуска нового проекта React Native на Expo. В разделе « Управляемый рабочий процесс» выберите пустой , введите «RNPokeSearch» в качестве имени проекта и установите зависимости с помощью Yarn:

 expo init RNPokeSearch 

Как и в веб-среде, вы можете устанавливать библиотеки для простой реализации различных функций в React Native. После создания проекта нам нужно установить пару зависимостей: pokemon и axios . Первый используется для проверки того, является ли текст, введенный в поле поиска, настоящим именем Pokemon, а axios используется для выполнения HTTP-запроса к используемому нами API: PokeAPI :

 yarn add pokemon axios 

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

Реагировать на структуру каталогов собственного проекта

Прежде чем перейти к написанию кода, давайте сначала посмотрим на структуру каталогов стандартного проекта React Native:

Стандартная структура каталогов React Native

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

  • App.js : основной файл проекта. Здесь вы начнете разрабатывать свое приложение. Любые изменения, внесенные в этот файл, будут отображены на экране.
  • index.js : файл точки входа любого проекта React Native. Это отвечает за регистрацию файла App.js в качестве основного компонента.
  • package.json : куда добавляются имя и версии библиотек, которые вы установили для этого проекта.
  • node_modules : где хранятся установленные вами библиотеки. Обратите внимание, что здесь уже есть много папок, прежде чем вы установили две библиотеки ранее. Это потому, что React Native также имеет свои собственные зависимости. То же самое верно для всех других библиотек, которые вы устанавливаете.
  • src : действует как основная папка, в которой хранится весь исходный код, связанный с самим приложением. Обратите внимание, что это только соглашение. Название этой папки может быть любым. Некоторые люди также используют app .
  • android : где код, связанный с Android. React Native не является родным языком. Вот почему нам нужна эта папка для загрузки приложения Android.
  • ios : где находится код, связанный с iOS. Это выполняет то же самое, что и папка android , но для iOS.

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

Для пользователей Expo каталог вашего проекта будет выглядеть так:

Экспо проект каталог

Как видите, все почти так же. Разница лишь в том, что нет папок android и ios . Это потому, что Expo заботится о запуске приложения для вас на обеих платформах. Там также добавление папки assets . Здесь хранятся ресурсы приложения, такие как значки и заставки.

Запуск приложения

Теперь вы можете запустить приложение. Обязательно подключите устройство к компьютеру или откройте эмулятор Android или симулятор iOS, прежде чем сделать это:

 react-native run-android react-native run-ios 

Вы уже видели, как выглядит экран по умолчанию ранее.

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

 yarn start 

После запуска отобразится QR-код:

Экспо начало пряжи

Откройте клиентское приложение Expo и на вкладке проектов нажмите « Сканировать QR-код» . Это откроет приложение на вашем устройстве Android или iOS. Если у вас запущен эмулятор, вы можете нажать i, чтобы запустить его на симуляторе iOS, или кнопку a, чтобы запустить его на эмуляторе Android:

Экспо клиентское приложение

Если вы тестируете на реальном устройстве, встряхните его, чтобы появилось меню разработчика:

Реагировать на собственные настройки разработчика

Нажмите на следующее:

  • Включить Live Reload : автоматически перезагружает ваше приложение, когда вы нажимаете сохранить в любом из его исходного кода.
  • Start Remote JS Debugging : для отладки ошибок JavaScript в браузере. Вы также можете использовать для этого react-native log-android react-native log-ios , но удаленная отладка дает более приятные результаты, поэтому ее легче проверить.

Если вы хотите, вы также можете установить сервер отладки. Это позволяет отключить мобильное устройство от компьютера во время разработки приложения. Вы можете сделать это, выбрав Dev Settings в меню разработчика. Затем в разделе « Отладка » выберите « Сервер и порт отладки для устройства» . Откроется окно, в котором вы можете ввести внутренний IP-адрес вашего компьютера и порт, на котором работает Metro Bundler (обычно это порт 8081 ).

Метро Бандлер порт

После того, как вы установили это, выберите « Обновить» в меню разработчика, чтобы зафиксировать изменения. Теперь вы можете отключить устройство от компьютера. Обратите внимание, что каждый раз, когда вы устанавливаете пакет, вам необходимо подключить ваше устройство, выйти из Metro Bundler и снова запустить приложение (используя react-native run-android или react-native run-ios ). Это единственный способ, чтобы изменения вступили в силу.

Кодирование приложения

Оба стандартных проекта React Native и Expo имеют встроенные компоненты, которые вы можете использовать для достижения желаемого. Просто покопайтесь в документации, и вы найдете информацию о том, как реализовать то, что вам нужно. В большинстве случаев вам нужен либо конкретный компонент пользовательского интерфейса, либо SDK, который работает со службой, которую вы планируете использовать. Вы можете использовать Native Directory для поиска тех или просто старых Google. Чаще всего ваш рабочий процесс будет выглядеть так:

  1. Ищите существующий пакет, который реализует то, что вы хотите.
  2. Установите это.
  3. Ссылка это — только для родных модулей. Если вы находитесь в Expo, вам не нужно делать это, потому что вы можете установить только чистые библиотеки JavaScript — хотя это может скоро измениться из-за введения unimodules и простого рабочего процесса .
  4. Используйте его в своем проекте.

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

Начните с замены содержимого файла App.js следующим кодом:

 import React from 'react'; import Main from './src/Main'; function App() { return <Main /> } export default App; 

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

Во второй строке мы импортируем пользовательский компонент с именем Main . Мы создадим это позже. А пока, знайте, что именно здесь мы разместим большую часть нашего кода.

После этого мы создаем компонент, создавая новую функцию. Все, что делает эта функция — возвращает Main компонент.

Наконец, мы экспортируем класс, чтобы он мог быть импортирован в другое место. В этом случае он фактически импортируется из файла index.js .

Затем создайте файл src/Main.js и добавьте следующее:

 // src/Main.js import React, { Component } from 'react'; import { SafeAreaView, View, Text, TextInput, Button, Alert, StyleSheet, ActivityIndicator } from 'react-native'; 

Вторая строка импортирует компоненты, встроенные в React Native. Вот что делает каждый из них:

  • SafeAreaView : для отображения содержимого в границах безопасной области устройства. Это автоматически добавляет заполнение, которое оборачивает его содержимое, чтобы оно не отображалось на выемках камеры и в области корпуса датчика устройства.
  • View : фундаментальный строительный блок пользовательского интерфейса. В основном это используется в качестве оболочки для всех других компонентов, поэтому они структурированы таким образом, что вы можете легко их оформить. Думайте об этом как о эквиваленте <div> : если вы хотите использовать Flexbox, вы должны использовать этот компонент.
  • Text : для отображения текста.
  • TextInput : компонент пользовательского интерфейса для ввода текста. Этот текст может быть простым текстом, электронным письмом, паролем или цифровой клавиатурой.
  • Button : для отображения Button для конкретной платформы. Этот компонент выглядит по-разному в зависимости от платформы, на которой он работает. Если это Android, он использует Material Design. Если это iOS, он использует Купертино.
  • Alert : для отображения предупреждений и подсказок.
  • ActivityIndicator : для отображения индикатора загрузки анимации.
  • StyleSheet : для определения стилей компонента.

Затем импортируйте библиотеки, которые мы установили ранее:

 import axios from 'axios'; import pokemon from 'pokemon'; 

Мы также будем создавать пользовательский компонент Pokemon позже. Этот используется для отображения данных покемонов:

 import Pokemon from './components/Pokemon'; 

Поскольку получение необходимых данных Pokemon включает в себя два запроса API, мы должны установить базовый URL API как константу:

 const POKE_API_BASE_URL = "https://pokeapi.co/api/v2"; 

Затем определите класс компонента и инициализируйте его состояние:

 export default class Main extends Component { state = { isLoading: false, // decides whether to show the activity indicator or not searchInput: '', // the currently input text name: '', // Pokemon name pic: '', // Pokemon image URL types: [], // Pokemon types array desc: '' // Pokemon description } // next: add render() method } 

В приведенном выше коде мы определяем основной компонент приложения. Вы можете сделать это, определив класс ES6 и расширив класс Component React. Это еще один способ определения компонента в React. В файле App.js мы создали функциональный компонент . На этот раз мы создаем компонент на основе классов .

Основное различие между ними заключается в том, что функциональные компоненты используются только в целях презентации. Функциональным компонентам нет необходимости сохранять свое собственное состояние, потому что все необходимые им данные просто передаются им через реквизиты. С другой стороны, компоненты на основе классов поддерживают свое собственное состояние, и обычно они передают данные функциональным компонентам.

Если вы хотите узнать больше о разнице между функциональными и основанными на классах компонентами, прочитайте это руководство: Функциональные против Классовых компонентов в React .

Возвращаясь к коду, мы инициализируем состояние внутри нашего компонента. Вы определяете это как простой объект JavaScript. Любые данные, которые входят в состояние, должны отвечать за изменение того, что отображается компонентом. В этом случае мы устанавливаем isLoading для управления видимостью индикатора активности и searchInput для отслеживания входного значения в поле поиска.

Это важная концепция для запоминания. Встроенные компоненты React Native и даже созданные вами пользовательские компоненты принимают свойства, управляющие следующим:

  • что отображается на экране (источник данных)
  • как они это представляют (структура)
  • как это выглядит (стили)
  • какие действия выполнять при взаимодействии пользователя (функции)

Мы рассмотрим эти свойства более подробно в следующем разделе. А пока знайте, что значение этих свойств обычно обновляется через состояние.

Остальные значения состояния предназначены для данных покемонов. Хорошей практикой является установка начального значения с тем же типом данных, который вы ожидаете сохранить позже — это также служит документацией.

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

 class Main extends Component { this.appTitle = "RNPokeSearch"; } 

В качестве альтернативы, его можно определить как переменную вне класса, так же, как мы делали ранее с POKE_API_BASE_URL :

 const POKE_API_BASE_URL = ''; class Main extends Component { } 

Структурирование и стилизация компонентов

Вернемся к определению класса компонента. Когда вы расширяете класс Component React, вы должны определить метод render() . Он содержит код для возврата пользовательского интерфейса компонента и состоит из компонентов React Native, которые мы импортировали ранее.

Каждый компонент имеет свой набор реквизита. Это в основном атрибуты, которые вы передаете компоненту для управления определенным его аспектом. В приведенном ниже коде большинство из них имеют style опору, которая используется для изменения стилей компонента. Вы можете передать любой тип данных в качестве реквизита. Например, onChangeText объекта TextInput является функцией, а onChangeText types в Pokemon представляет собой массив объектов. Позже в компоненте Pokemon вы увидите, как будут использоваться реквизиты:

 render() { const { name, pic, types, desc, searchInput, isLoading } = this.state; // extract the Pokemon data from the state return ( <SafeAreaView style={styles.wrapper}> <View style={styles.container}> <View style={styles.headContainer}> <View style={styles.textInputContainer}> <TextInput style={styles.textInput} onChangeText={(searchInput) => this.setState({searchInput})} value={this.state.searchInput} placeholder={"Search Pokemon"} /> </View> <View style={styles.buttonContainer}> <Button onPress={this.searchPokemon} title="Search" color="#0064e1" /> </View> </View> <View style={styles.mainContainer}> { isLoading && <ActivityIndicator size="large" color="#0064e1" /> } { !isLoading && <Pokemon name={name} pic={pic} types={types} desc={desc} /> } </View> </View> </SafeAreaView> ); } 

Разбивая код выше, мы сначала извлекаем данные о состоянии:

 const { name, pic, types, desc, searchInput, isLoading } = this.state; 

Далее мы возвращаем интерфейс компонента, который следует этой структуре:

 SafeAreaView.wrapper View.container View.headContainer View.textInputContainer TextInput View.buttonContainer Button View.mainContainer ActivityIndicator Pokemon 

Вышеуказанная структура оптимизирована для использования Flexbox. Идем дальше и определяем стили компонентов в нижней части файла:

 const styles = StyleSheet.create({ wrapper: { flex: 1 }, container: { flex: 1, padding: 20, backgroundColor: '#F5FCFF', }, headContainer: { flex: 1, flexDirection: 'row', marginTop: 100 }, textInputContainer: { flex: 2 }, buttonContainer: { flex: 1 }, mainContainer: { flex: 9 }, textInput: { height: 35, marginBottom: 10, borderColor: "#ccc", borderWidth: 1, backgroundColor: "#eaeaea", padding: 5 } }); 

В React Native вы определяете стили, используя StyleSheet.create() и передавая объект, содержащий ваши стили. Эти определения стилей в основном являются объектами JavaScript, и они следуют той же структуре, что и ваши обычные стили CSS:

 element: { property: value } 

wrapper и container настроены на flex: 1 , что означает, что они будут занимать все доступное пространство, потому что у них нет братьев и сестер. React Native по умолчанию использует flexDirection: 'column' , что означает, что он будет располагать элементы flex по вертикали, например:

столбец направления гибкого трубопровода

Напротив, ( flexDirection: 'row' ) flexDirection: 'row' элементы горизонтально:

гибкий ряд

Он отличается от headContainer , потому что, хотя он настроен на flex: 1 , он имеет mainContainer качестве родственного mainContainer . Это означает, что headContainer и mainContainer будут совместно использовать одно и то же пространство. mainContainer имеет значение flex: 9 поэтому он будет занимать большую часть доступного пространства (около 90%), в то время как headContainer будет занимать только около 10%.

Давайте перейдем к содержанию headContainer . Он имеет textInputContainer и buttonContainer качестве своих дочерних buttonContainer . Для него установлено значение flexDirection: 'row' , так что его дочерние flexDirection: 'row' будут расположены горизонтально. Тот же принцип применяется в отношении совместного использования пространства: textInputContainer занимает две трети доступного горизонтального пространства, в то время как buttonContainer занимает только одну треть.

Остальные стили довольно понятны, если у вас есть CSS-фон. Просто не забудьте опустить - и установить следующий символ в верхнем регистре. Например, если вы хотите установить background-color , эквивалентом React Native будет backgroundColor .

Примечание: не все свойства CSS, доступные в Интернете, поддерживаются в React Native. Например, такие вещи как свойства с плавающей точкой или таблицы не поддерживаются. Вы можете найти список поддерживаемых свойств CSS в документации для компонентов View и Text . Кто-то также подготовил шпаргалку React Native Styling . В документации также есть раздел стилей для конкретного компонента React Native, который вы хотите использовать. Например, вот свойства стиля, которые вы можете использовать для компонента Image .

Обработка событий и обновление состояния

Давайте теперь разберем код для компонентов TextInput и Button . В этом разделе мы поговорим об обработке событий, выполнении HTTP-запросов и обновлении состояния в React Native.

Давайте начнем с изучения кода для TextInput :

 <TextInput style={styles.textInput} onChangeText={(searchInput) => this.setState({searchInput})} value={searchInput} placeholder={"Search Pokemon"} /> 

В приведенном выше коде мы устанавливаем функцию для выполнения, когда пользователь вводит что-то в компонент. Обработка событий, подобных этим, аналогична обработке в DOM: вы просто передаете имя события как реквизит и устанавливаете его значение для функции, которую хотите выполнить. В этом случае мы просто добавляем это, потому что мы просто обновляем состояние. Введенное пользователем значение автоматически передается в качестве аргумента в указанную вами функцию, поэтому все, что вам нужно сделать, это обновить состояние с помощью этого значения. Не забудьте установить значение TextInput равным значению переменной состояния. В противном случае значение, введенное пользователем, не будет отображаться при вводе.

Далее мы переходим к компоненту Button . Здесь мы onPress событие onPress :

 <Button onPress={this.searchPokemon} title="Search" color="#0064e1" /> 

После нажатия выполняется функция searchPokemon() . Добавьте эту функцию прямо под методом render() . Эта функция использует шаблон async / await, потому что выполнение HTTP-запроса является асинхронной операцией. Вы также можете использовать Promises, но для краткости нашего кода вместо этого мы будем использовать async / await. Если вы не знакомы с ним, обязательно прочитайте этот урок :

 render() { // ... } searchPokemon = async () => { try { const pokemonID = pokemon.getId(this.state.searchInput); // check if the entered Pokemon name is valid this.setState({ isLoading: true // show the loader while request is being performed }); const { data: pokemonData } = await axios.get(`${POKE_API_BASE_URL}/pokemon/${pokemonID}`); const { data: pokemonSpecieData } = await axios.get(`${POKE_API_BASE_URL}/pokemon-species/${pokemonID}`); const { name, sprites, types } = pokemonData; const { flavor_text_entries } = pokemonSpecieData; this.setState({ name, pic: sprites.front_default, types: this.getTypes(types), desc: this.getDescription(flavor_text_entries), isLoading: false // hide loader }); } catch (err) { Alert.alert("Error", "Pokemon not found"); } } 

Разбивая код выше, мы сначала проверяем, является ли введенное имя покемонов действительным. Если он действителен, возвращается национальный идентификатор Pokedex (если вы открываете ссылку, это число сверху имени покемона), и мы предоставляем его в качестве параметра для HTTP-запроса. Запрос сделан методом axios get(), который соответствует HTTP-запросу GET. Как только данные доступны, мы извлекаем то, что нам нужно, и обновляем состояние.

Вот getTypes()функция. Все это делает переназначить slotи typeсвойство типов покемонов к idи name:

 getTypes = (types) => { return types.map(({ slot, type }) => { return { "id": slot, "name": type.name } }); } 

Вот getDescription()функция. Это находит первую английскую версию flavor_text:

 getDescription = (entries) => { return entries.find(item => item.language.name === 'en').flavor_text; } 

Покемон Компонент

Ранее мы импортировали и использовали компонент под названием Pokemon, но мы еще не создали его. Давайте продолжим и сделаем это. Создайте src/components/Pokemon.jsфайл и добавьте следующее:

 // src/components/Pokemon.js import React from 'react'; import { View, Text, Image, FlatList, StyleSheet } from 'react-native'; const Pokemon = ({ name, pic, types, desc }) => { if (!name) { return null } return ( <View style={styles.mainDetails}> <Image source={{uri: pic}} style={styles.image} resizeMode={"contain"} /> <Text style={styles.mainText}>{name}</Text> <FlatList columnWrapperStyle={styles.types} data={types} numColumns={2} keyExtractor={(item) => item.id.toString()} renderItem={({item}) => { return ( <View style={[styles[item.name], styles.type]}> <Text style={styles.typeText}>{item.name}</Text> </View> ) }} /> <View style={styles.description}> <Text>{desc}</Text> </View> </View> ); } // const styles = StyleSheet.create({ mainDetails: { padding: 30, alignItems: 'center' }, image: { width: 100, height: 100 }, mainText: { fontSize: 25, fontWeight: 'bold', textAlign: 'center' }, description: { marginTop: 20 }, types: { flexDirection: 'row', marginTop: 20 }, type: { padding: 5, width: 100, alignItems: 'center' }, typeText: { color: '#fff', }, normal: { backgroundColor: '#8a8a59' }, fire: { backgroundColor: '#f08030' }, water: { backgroundColor: '#6890f0' }, electric: { backgroundColor: '#f8d030' }, grass: { backgroundColor: '#78c850' }, ice: { backgroundColor: '#98d8d8' }, fighting: { backgroundColor: '#c03028' }, poison: { backgroundColor: '#a040a0' }, ground: { backgroundColor: '#e0c068' }, flying: { backgroundColor: '#a890f0' }, psychic: { backgroundColor: '#f85888' }, bug: { backgroundColor: '#a8b820' }, rock: { backgroundColor: '#b8a038' }, ghost: { backgroundColor: '#705898' }, dragon: { backgroundColor: '#7038f8' }, dark: { backgroundColor: '#705848' }, steel: { backgroundColor: '#b8b8d0' }, fairy: { backgroundColor: '#e898e8' } }); export default Pokemon; 

В приведенном выше коде мы сначала проверили, nameимеет ли ложное значение. Если это так, мы просто возвращаемся, так nullкак нечего визуализировать

Мы также используем два новых встроенных компонента React Native:

  • Image : используется для отображения изображений из Интернета или из файловой системы
  • FlatList : используется для отображения списков

Как мы видели ранее, мы передаем данные Pokemon в качестве опоры для этого компонента. Мы можем извлечь эти реквизиты так же, как извлекаем отдельные свойства из объекта:

 const Pokemon = ({ name, pic, types, desc }) => { // .. } 

ImageКомпонент требует , sourceчтобы передать ему. Это sourceможет быть изображение из файловой системы или, в данном случае, изображение из Интернета. Первый требует, чтобы изображение было включено с помощью require(), в то время как второй требует, чтобы URL-адрес изображения использовался как значение uriсвойства объекта, который вы ему передаете.

resizeModeпозволяет контролировать, как будет изменяться размер изображения в зависимости от его контейнера. Мы использовали contain, что означает, что оно изменит размер изображения так, чтобы оно вписывалось в его контейнер, сохраняя при этом его соотношение сторон. Обратите внимание, что контейнер — это Imageсам компонент. Мы установили его widthи heightна 100, поэтому изображение будет изменено в соответствии с этими размерами. Если исходное изображение имеет ширину, превышающую его высоту, будет использоваться ширина 100, а высота будет соответствующим образом регулироваться для сохранения соотношения сторон. Если исходный размер изображения меньше, он просто сохранит свой исходный размер:

 <Image source={{uri: pic}} style={styles.image} resizeMode={"contain"} /> 

Далее идет FlatListкомпонент. Используется для рендеринга списка предметов. В этом случае мы используем его для визуализации типов покемонов. Для этого требуется data, который является массивом, содержащим элементы, которые вы хотите визуализировать, и renderItemфункцией, которая отвечает за отображение каждого элемента в списке. К элементу в текущей итерации можно обращаться так же, как к реквизиту в функциональном компоненте:

 <FlatList columnWrapperStyle={styles.types} data={types} numColumns={2} keyExtractor={(item) => item.id.toString()} renderItem={({item}) => { return ( <View style={[styles[item.name], styles.type]}> <Text style={styles.typeText}>{item.name}</Text> </View> ) }} /> 

В приведенном выше коде мы также поставили следующие реквизиты:

  • columnWrapperStyle: используется для определения стилей для каждого столбца. В этом случае мы хотим сделать каждый элемент списка встроенным, поэтому мы указали flexDirection: 'row'.
  • numColumns: максимальное количество столбцов, которое вы хотите отобразить для каждой строки в списке. В данном случае мы указали 2, потому что у покемона может быть только два типа.
  • keyExtractor: функция, используемая для извлечения ключей для каждого элемента. Вы можете на самом деле опустить этот, если вы передадите keyопору внешнему компоненту каждого из элементов списка.

Теперь вы можете протестировать приложение на своем устройстве или эмуляторе:

 react-native run-android react-native run-ios yarn start 

Заключение и последующие шаги

Это оно!Из этого руководства вы узнали, как настроить среду разработки React Native, используя как стандартную процедуру, так и Expo. Вы также узнали, как создать свое самое первое приложение React Native.

Чтобы узнать больше, ознакомьтесь с этими ресурсами:

Вы можете найти исходный код, используемый в этом руководстве, в этом репозитории GitHub .