В этом уроке мы собираемся создать простой клон Snapchat. Этот пример будет имитировать самые ранние версии Snapchat, а не более надежную сегодняшнюю версию, в которой есть «истории» и функции дополненной реальности. Этот урок будет ближе к Snapchat примерно 2013 года.

Это руководство выполнено на Mac и будет включать ярлыки Mac с помощью клавиши cmd. Код терминала обозначается одной строкой, начинающейся с $ .

Часть 1: Настройка среды и общего каталога

Во-первых, убедитесь, что React-Native cli установлен глобально:

$ npm i -g react-native-cli

На момент записи версия cli - 2.0.1, а версия React-Native - 0.48.3.

Теперь мы создадим новый проект:

$ react-native init snapchatClone

Вам также потребуется установленный Node. Проверьте, установлено ли оно у вас:

$ node -v

На момент записи текущая версия 6.11.3, но используется 6.10.3 - либо работает.

Теперь смените каталог на свой проект:

$ cd snapchatClone

Запустите $ npm install.

Затем запустите $ react-native start. Запустите это как для iOS, так и для Android. Это задача фонового компоновщика, которая заботится о многих вещах за кулисами, таких как объединение вашего кода, загрузка файлов и запуск его для Native. Оставьте это на отдельной вкладке терминала.

На второй вкладке для iOS: запустите $ react-native run-ios (в первый раз это займет несколько минут). Эмулятор должен появиться во время выполнения этой команды.

Для Android требуется дополнительный шаг. Измените свой каталог и добавьте файл:

$ cd android
$ touch local.properties

В новом файле local.properties добавьте ссылку-указатель для того, где хранится ваш Android SDK, набрав sdk.dir = /Users/your_username_here/Library/Android/sdk. Сохраните ваш файл.

В Android Studio, Virtual Device Manager, у вас должен быть уже загружен API вашего устройства. Запустите Android Emulator, нажав зеленую кнопку воспроизведения слева от строки.

Теперь, когда ваш эмулятор уже открыт (в противном случае это вызовет сбой) run$ react-native run-android в Терминале.

Включите «Горячую перезагрузку», набрав cmd + D (iOS) cmd + M (Android) в окне эмулятора и выбрав соответствующий параметр. Это будет перезагружать эмулятор при каждом сохранении (главный аргумент в пользу платформы React-Native). Иногда эта функция работает некорректно. Если вы не получаете желаемого результата, попробуйте принудительно перезагрузить с помощью cmd + R, прежде чем проверять наличие ошибок в коде.

Найдите файл index.ios.js или index.android.js в своем проекте. Каждый раз, когда запускается React-Native, он ищет эти индексные файлы в качестве точки входа. Мы можем разработать общий компонент обоих этих файлов, чтобы избежать дублирования кода для обеих платформ.

Давайте создадим исходный каталог на третьей вкладке Терминала, затем перейдем в него и создадим файл с именем App.js - убедитесь, что ваш текущий каталог является корнем вашего проекта.

$ mkdir src
$ cd src
$ touch App.js

Так запускается каждый компонент в React. Импортируйте React и Component. Ваш новый компонент, App, будет расширен Component. Тогда вам понадобится функция render() и return.

Теперь мы собираемся просто вырезать и вставить стили из наших «индексных» файлов. В index.android.js или index.ios.js (одинаковый код таблицы стилей для обоих) найдите код ниже и вставьте его под своим App классом в App.js. Удалите повторяющийся код в индексном файле, из которого вы не вырезали.

Кроме того, мы вырезать и вставить код ниже также из любого индексного файла (опять же, удалив код из того файла, который вы не вырезали от). Также удалите StyleSheet, Text и View из импортированных в «индексных» файлах (оставив только AppRegistry).

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

Мы удалим текстовые сообщения, кроме «Добро пожаловать в React».

Теперь в обоих индексных файлах импортируйте App и добавьте тег <App /> в свою render() функцию.

Теперь у нас есть общий каталог для разработки исходного кода, что избавляет нас от беспокойства по поводу дублирования кода как для iOS, так и для Android.

Часть 2: Реализация заголовка и списка сообщений

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

Поскольку React и Javascript настолько гибкие, легко развить плохие методы или получить проблемы, передавая вещи туда и обратно. Большинство людей в сообществе React-Native создают компоненты трех типов: презентационные, контейнерные и макетные.

В терминале убедитесь, что вы находитесь в исходном каталоге. Затем создайте каталог компонентов, перейдите в него и создайте еще три каталога: контейнеры, макет и презентацию.

$ mkdir components
$ cd components
$ mkdir containers layout presentation

Перейдите в новый каталог макета и создайте два файла: index.js и Home.js.

$ cd layout
$ touch index.js Home.js

Теперь в вашем index.js файле импортируйте и экспортируйте Home.

Это позволяет нам, например, в index.ios.js импортировать App из прямой ссылки на файл. Но теперь, когда мы хотим импортировать, мы можем просто ссылаться на сам каталог, а не на файл. Итак, если нам нужно импортировать пятнадцать компонентов, вместо 15 строк импорта из разных файлов одного каталога, теперь у нас может быть только одна строка.

Откройте ваш Home.js файл, который будет стандартным компонентом реакции, и создайте свою стандартную функцию рендеринга.

Теперь переместим все из App.js в Home.js и импортируем Home в App.js. Мы удалим наш импорт Text и StyleSheet, а также блок instructions в нашей таблице стилей. Ниже приведены App.js и Home.js после изменений.

Обязательно сохраните свои файлы. App.js теперь ваш корневой каталог. Мы только что выполнили базовую работу для остальной части нашего проекта. Теперь мы создадим компонент заголовка в Home.js.

Перейдите в папку презентации в Терминале и создайте файлы index.js и Header.js.

$ cd ../presentation
$ touch index.js Header.js

В index.js импортируйте и экспортируйте Header.

В Header.js настройте свой стандартный компонент реакции, импортировав View, Text, StyleSheet.

Теперь импортируйте и renderHeader в Home.js.

Компоненты могут получать атрибуты двумя способами: состояние (обычно содержится внутри компонента) и свойство (обычно передается или передается другим компонентом вашим компонентом). Мы дадим заголовку текстовую опору с цветом. Ниже будет показан только измененный код функции рендеринга в пределах Home.js.

Вернемся к Header.js, мы будем использовать componentDidMount метод жизненного цикла. Это вызывается только один раз при монтировании компонента. Перезагрузка нашего эмулятора должна дать нам предупреждение с помощью свойства text.

Мы можем удалить componentDidMount жизненный цикл, сослаться на текст опоры в рендере заголовка и создать таблицу стилей. Мы изменим цвет фона текста «Все сообщения» и переместим его в верхнюю часть экрана с некоторым отступом от строки состояния. Мы также можем настроить ширину и отступ ниже, чтобы создать заголовок, как у Snapchat. Нам нужно импортировать StatusBar и изменить barStyle на свет, чтобы он отображался на нашем фоне.

Теперь мы удалим текст «Добро пожаловать…» в Home.js в рамках подготовки к нашему новому Messages контейнеру, а также добавим новый импорт. Приведенный ниже код исключает код таблицы стилей в файле, который остается неизменным.

В терминале перейдите в каталог контейнеров и создайте index.js и Messages.js.

$ cd ../containers
$ touch index.js Messages.js

В index.js напишите обычный импорт и экспорт и настройте Messages.js как стандартный компонент вместе с View, StyleSheet, Text, FlatList, TouchableOpacity импортом.

Теперь давайте создадим обычный массив сообщений, а затем переместим их на сервер после того, как мы все настроим и заработаем. Мы будем использовать constructor() метод класса React. Важно отметить, что каждый компонент React имеет собственное локальное состояние. Ключевым аспектом React является то, что каждое представление является детерминированным, отслеживая свои собственные значения, особенно его локальное состояние. Мы создадим объект состояния myObj:0. Измените наш рендеринг с тега View на TouchableOpacity с нашим объектом в качестве текста. Мы также можем реализовать метод add() для увеличения значения объекта, когда мы «касаемся» его.

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

Мы можем удалить myObj объект, add() функцию и сенсорный текст, поскольку это был всего лишь пример. Настройте массив сообщений в конструкторе. Используйте тег FlatList в функции рендеринга, добавив renderItem к вызову функции, указав, как мы хотим, чтобы элемент рендерился. Вызываемая им функция будет _renderMessage(item). В дополнение к renderItem нам понадобится data источник. Сначала мы передадим статические данные, чтобы проверить, работает ли код, а затем перейдем к динамическим данным.

Теперь удалите статическое сообщение в _renderMessage(item) и замените его динамической реализацией. Нам нужно добавить стиль к нашей render() функции и создать таблицу стилей ниже.

В Header.js мы можем немного скорректировать нашу таблицу стилей и дать заголовку верхнее поле в пределах Home.js, чтобы сообщения отображались под заголовком. (Ниже будет представлен только измененный код в каждом файле.)

Есть более эффективные способы справиться с этим с помощью Flexbox, но основное внимание в этом руководстве не уделяется стилям, поэтому то, что у нас есть, пока годится (более поздние учебные пособия могут быть более подробными с Flexbox).

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

В Messages.js добавьте встроенный стиль к тегу представления вместе с добавлением стиля message в таблицу стилей. Затем добавьте встроенный стиль массив к текстовому тегу в _renderMessage(item). В массиве укажите отступы сверху и снизу 5 и настраиваемый текст, который мы укажем в нашей таблице стилей с помощью messageText.

Предупреждение VirtualizedList внизу эмулятора вызвано тем, что React требует ключа для каждого элемента списка. Мы можем исправить это, реализовав опору keyExtractor в нашем FlatList рендере. (Ниже представлена ​​только измененная render() функция Messages.js)

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