Изучите React Native: введение, навигация, хранилище данных и собственный модуль

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

Лучший способ чему-либо научиться - это делать это!

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

Создавая приложение, я узнал о различных компонентах, таких как навигация, хранение данных, вызовы API и т. Д. Каждый из них очень важен, и я объясню каждый из них. Используя эти компоненты, можно создать любое приложение.

Что мы собираемся осветить?

Создайте QR-сканер для собственного приложения, который сканирует QR-код, хранит его в локальном хранилище и, в конце концов, делает его красивым. Это будет долгое руководство, так что возьмите себе чашку кофе и сидите спокойно. Ориентировочно, это займет около 1:30–2 часа, но…

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

Исходный код

Код приложения доступен на GitHub. Вы можете получить код приложения в соответствии с версией приложения, проверив конкретную ветку. Например, чтобы получить код приложения v0.3.0,

git clone https://github.com/drex44/QR-Scanner.git
git checkout v0.3.0

Код состоит из трех ветвей,

  • master: код для QR Scanner v1.0.0
  • v0.3.0: код для QR Scanner v0.3.0
  • v0.4.0: код для QR Scanner v0.4.0

Руководство

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

Да пребудет с вами сила и пусть начнется взлом!

v0.1.0

Цели: приложение Hello World, использование библиотеки пользовательского интерфейса, тестирование вашего приложения

Мы можем создать собственное приложение для реагирования с помощью двух известных наборов инструментов. Один - expo, другой - react-native.

Как говорится в официальных документах,

Expo - это бесплатный набор инструментов с открытым исходным кодом, созданный на основе React Native, который поможет вам создавать собственные проекты для iOS и Android с использованием JavaScript и React.

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

Если вы хотите использовать какой-либо собственный модуль, такой как камера, служба определения местоположения и т. Д., Вам необходимо использовать модуль npm, который будет содержать некоторый собственный код для конкретной платформы, а затем вам необходимо связать его. Вы даже можете создавать свои собственные собственные модули, написав собственный код, но тогда это не будет чистый javascript.

Основное преимущество использования expo toolchain заключается в том, что они поддерживают собственный модуль, так что мы можем сосредоточиться на создании нашего приложения. Обновлять и поддерживать приложение также очень просто. Но в то же время у вас меньше контроля над своим приложением, чем у react-native-cli.

Поэтому, когда мы хотим быстро создавать приложения, используйте expo. Как только приложение вырастет, можно выполнить извлечение (аналогично извлечению CRA), и оно будет преобразовано в набор инструментов для реагирования.

Теперь перейдем к кодированию и создадим наше первое приложение. Выполните команду ниже, чтобы установить expo-cli, а затем создать новый проект, используя его. Вам будет предложено выбрать шаблон, выбрать «пустой».

npm install -g expo-cli
expo init qr-scanner

Откройте свою любимую IDE и отредактируйте App.js. Это ваша основная точка входа в приложение. Мы не можем использовать элементы HTML в приложении React Native. Мы должны использовать компоненты React Native. Вставьте приведенный ниже код в свой App.js,

App.js

Мы только что изменили текст внутри компонента Text на Hello World!. Компонент Просмотр является строительным блоком в реагирующих нативных приложениях. Он используется так же, как элемент div в веб-приложении. Пришло время запустить приложение. У Expo есть Клиентское приложение для iOS / Android. вам понадобится клиент expo для запуска приложения или, если вы предпочитаете использовать эмулятор, вам необходимо настроить студию Android для Android и xcode для IOS. Использование клиента expo происходит быстро, и мы можем начать работу в течение нескольких минут, поэтому мы будем использовать клиент expo. Загрузите его на свое устройство, а затем выполните команду ниже в корне проекта,

npm start

Теперь откройте свой клиент выставки на мобильном устройстве и отсканируйте QR-код. Убедитесь, что ваш компьютер и мобильное устройство находятся в одной сети. Если это не так, вы можете создать и войти в свою учетную запись expo на своем компьютере и мобильном устройстве, чтобы протестировать приложение через Интернет. Поздравляем, вы успешно создали и запустили собственное приложение.

Результат

Вы можете ознакомиться с официальными нативными компонентами React в документации, а также создать собственные компоненты пользовательского интерфейса. По мере того, как росла потребность в создании более совершенных компонентов, решение предлагалось различными пакетами с открытым исходным кодом. Некоторые из известных опций: Native Base, React Native Elements, Shoutem-UI. Мы будем использовать Native Base.

Установите Native Base, react-native-easy-grid (для макетов) и векторные иконки (для иконок),

npm install native-base --save
npm install @expo/vector-icons --save
npm install react-native-easy-grid --save
npm install
or
yarn add native-base --save
yarn add @expo/vector-icons --save
yarn add react-native-easy-grid --save
yarn

Теперь измените App.js с помощью приведенного ниже кода,

App.js

Результат

Для получения дополнительной информации ознакомьтесь с Нативными базовыми компонентами.

Код, написанный в componentWillMount (), предназначен для загрузки шрифтов перед отрисовкой компонента. Эти шрифты используются Native Base внутри, и это вызовет ошибку времени выполнения, если они не будут загружены до визуализации компонента.

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

v0.2.0

Цели: Навигация

Подобно тому, как можно использовать URL / маршруты для структурирования веб-приложения, необходимо использовать разные экраны в собственном приложении. Мы в основном создаем разные экраны и вызываем каждый экран на основе некоторого пользовательского ввода и предопределенных условий в App.js (помните, App.js - это единственная точка входа в нашем приложении). Мы можем создать собственный механизм навигации и обрабатывать разные экраны, показывая / скрывая различные компоненты внутри нашего App.js, но мы не хотим изобретать велосипед.

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

npm install --save react-navigation

Создайте новую папку с именем components и новый файл с именем Navigation.js в ней. Скопируйте приведенный ниже код в Navigation.js,

компоненты / Navigation.js

Код очень простой. Мы создаем три экрана: «Сканер», «История» и «Результат». Экраны - не что иное, как реагирующий компонент. Здесь мы создали три компонента с именами ScannerScreen, HistoryScreen и ResultScreen. Затем мы создаем RootStack, в котором определяем имена экранов и назначаем им компоненты React. т.е. мы присвоили компоненту ScannerScreen имя Scanner. Затем мы указываем начальный экран, который будет отображаться, указав initialRouteName. Наконец, мы экспортируем RootStack, помещая его в createAppContainer.

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

React navigation автоматически устанавливает объект «навигации» внутри свойств экрана, когда мы создаем стек. он используется для выполнения различных перемещений внутри экрана. Например, здесь, в ScannerScreen, мы использовали его для перехода к другим экранам, History и Result.

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

App.js

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

Результат

Если вам интересно узнать о панели навигации, то по умолчанию она добавляется с помощью интерактивной навигации, и ею можно управлять глобально, а также локально на каждом экране. Здесь мы настроили панель заголовка локально в каждом компоненте. т.е. в ScannerScreen мы полностью удалили заголовок. В HistoryScreen и ResultScreen мы назначили заголовки заголовков. Для получения дополнительной информации ознакомьтесь с разделом Настройка панели заголовка в официальных документах React Navigation.

Интересный факт: рассмотрим навигатор по стеку с экранами A и B. После перехода к A вызывается его componentDidMount. При нажатии B его componentDidMount также вызывается, но A остается смонтированным в стеке, и поэтому его componentWillUnmount не вызывается. При возврате от B к A вызывается componentWillUnmount из B, но componentDidMount из A не вызывается, потому что A все время оставался смонтированным. Чтобы преодолеть это, мы должны использовать события жизненного цикла, предоставляемые реагирующей навигацией.

v0.3.0

Цели: Как хранить данные локально.

Каждое собственное приложение должно хранить данные, такие как статус пользователя, статус входа в систему, конфигурацию приложения и т. Д. Мы можем использовать SecureStore, AsyncStorage, SQLite и Realm. Это наиболее распространенные и простые в использовании услуги.

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

SecureStore и AsyncStorage являются системами хранения значений ключей. Единственное различие между ними - способ хранения данных. SecureStore шифрует данные, а AsyncStorage хранит их в виде обычного текста.

Мы не будем использовать SecureStore или AsyncStorage. Мы будем использовать только SQLite в нашем приложении, но я упомянул их здесь, потому что они очень полезны и просты в использовании.

SecureStore

iOS: значения сохраняются с помощью служб связки ключей как kSecClassGenericPassword. iOS имеет дополнительную возможность установить атрибут значения kSecAttrAccessible, который контролирует, когда значение доступно для выборки.

Android: значения хранятся в SharedPreferences, зашифрованы с помощью системы хранилища ключей Android.

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

AsyncStorage

Он имеет тот же API, что и SecureStore. мы в основном используем следующие методы,

  • AsyncStorage.getItem(key)
  • AsyncStorage.setItem(key, value)
  • AsyncStorage.removeItem(key)

Чтобы узнать больше о методах, обратитесь к официальной документации выставки.

SQLite

Когда мы хотим сохранить большой объем структурированных данных, мы можем использовать SQLite. SQLite - это локальная облегченная база данных SQL.

Как упоминалось выше, альтернатива SQLite: Realm Database - это быстрая, простая в использовании альтернатива SQLite и Core Data с открытым исходным кодом.

Мы создадим новый объект базы данных из SQLite и выполним с ним некоторую транзакцию.

Создайте новый файл «components / SQL.js» и вставьте в него приведенный ниже код,

По мере роста компонентов Screen будет сложно сохранить его в Navigation.js. Итак, давайте разделим компоненты "Навигация" и "Экран". Создайте новую папку с именем Screens. Создайте три файла ScannerScreen.js, HistoryScreen.js и ResultScreen.js. Итак, Navigation.js теперь будет выглядеть так:

компоненты / Navigation.js

Используйте приведенный ниже код для каждого экрана.

Экраны / ScannerScreen.js

Экраны / HistoryScreen.js

Экраны / ResultScreen.js

Наконец, мы должны вызвать метод InitDatabase в App.js,

App.js

Вы можете добавить новую строку в базу данных, используя поле ввода. Введите что-нибудь и нажмите ДОБАВИТЬ В БД. Чтобы проверить сохраненные результаты, проверьте экран истории.

Результат

v0.4.0

Цели: Использование модулей камеры / BarCodeScanner от expo

Когда мы создаем собственное приложение, мы, скорее всего, будем использовать собственные функции. Перед использованием встроенных функций нам необходимо запросить разрешения на их использование. Мы можем сделать это, используя компонент Permission из expo. Мы попросим разрешения камеры. Другой модуль, который мы будем использовать - BarCodeScanner для сканирования штрих-кода. Это просто оболочка над модулем Камера (вы также можете использовать модуль Камера непосредственно для сканирования штрих-кода).

Откройте ScannerScreen.js и вставьте приведенный ниже код. Посмотрите на код и обратите внимание, что мы проверяем разрешения в методе componentDidMount (). После получения разрешения мы отображаем BarCodeScanner в полноэкранном режиме. Мы накладываем одну кнопку «История», чтобы проверить предыдущие отсканированные QR-коды.

Даже при сканировании QR-кода камера не останавливается и все равно пытается сканировать QR-коды. Таким образом, когда другой экран будет в фокусе, камера по-прежнему будет активна и продолжит сканировать QR-коды. Чтобы преодолеть это, мы обернули наш компонент в withNavigationFocus из react-navigation. Это дает нам метод isFocused в реквизитах, чтобы проверить, отображается ли ScannerScreen (Focused) на фактическом устройстве. Мы используем эту опору для условного рендеринга компонента BarCodeScanner.

Экраны / ScannerScreen.js

Экраны / ResultScreen.js

В компоненте ResultScreen мы просто извлекаем qr из параметров навигации и показываем его в компоненте Text.

Результат

Теперь приложение готово и работает, но пользовательский интерфейс не очень интуитивно понятен. Так что давайте исправим это и улучшим интерфейс.

v1.0.0

Цель: лучший пользовательский интерфейс

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

Создайте новый файл внутри компонентов с именем «commons.js» и вставьте приведенный ниже код.

компоненты / commons.js

Также измените код на экранах ниже.

HistoryScreen.js

ResultScreen.js

Экраны / ScannerScreen.js

Результат

Исходный код

Код приложения доступен на GitHub.

Домашнее задание

Если вы забудете то, чему научились, это будет пустой тратой времени. Итак, вот домашнее задание. Не торопитесь и доделайте это сами. Я нигде не предоставил никакого кода для этих задач. если возникнут трудности, прокомментируйте, и я отвечу на них.

  • Добавьте кнопку для удаления QR-кода в HistoryScreen и ResultScreen.
  • Добавьте кнопку (точки-три по горизонтали) в верхнем правом углу, чтобы открыть экран настроек.
  • Включите звук при успешном сканировании QR-кода. Дайте возможность на экране настроек изменить поведение.
  • Вибрируйте телефон после успешного сканирования QR-кода. Дайте возможность на экране настроек изменить поведение.

Подсказка: сохраните настройки звука и вибрации в AsyncStorage.

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

Следующий

Я попытался осветить многие темы в этой статье, но она оказалась очень длинной, и поэтому я не смог охватить раздел API. Поэтому я расскажу, как выполнить аутентификацию пользователя и синхронизировать данные с сервером, в статье React Native для начинающих 2.0, где мы создадим QR Scanner v2.0.0.

Заключение

Продолжайте учиться, и да пребудет с вами сила. Если вам нужна статья на любую тему, дайте мне знать. Я сделаю все возможное, чтобы помочь вам. Если у вас есть вопросы или предложения, то оставьте их в комментариях ниже.

P.S. Если вы нашли эту статью полезной, хлопайте в ладоши! 👏👏👏 Это приятно и дает мне мотивацию продолжать писать.