React Native с колокольни Android разработки часть 2

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

    Инструменты


    Еще раз хочу осветить тему рабочих инструментов. React native еще не очень близок к версии, хотя бы, 1.0, чему и причина отсутствия полностью рабочего и заточенного под этот продукт IDE. Хотя, внезапно, я наткнулся на это: Deco IDE. Да, это самая настоящая IDE (только под macOS по понятным причинам), да еще и купленная airbnb. Но не все так радужно как оказалось. Да, тут можно «программировать мышкой» просто перетаскивая компоненты в код. Опять же, есть список компонентов, не нужно каждый раз лезть на оф. сайт, чтобы узнать, а какой компонент еще там есть. Так же можно запустить проект буквально 1 тыком (правда, только iOS, с андроидом всегда проблемы). Но на этом все фишки и кончаются. Тут нету ни быстрых переходов к компонентам по клику с зажатым cmd, нету даже адекватного линтера и автодополнения. По функционалу кодинга — это простой блокнот, который только не закрытый тэг сможет подсветить. Но теперь этим инструментом занята крупная компания, надеюсь на его скорое развитие.

    В большинстве видео про react native, а так же в скриншотах различных статей я везде видел VS code. Штука действительно неплохая, спокойно подцепляется eslinter как плагин, можно подцепить flow, есть автокомплиты и даже переходы к компонентам. Есть встроенный git и даже интегрированный терминал. И я бы тоже его использовал, но есть огромный для меня минус — по дефолту каждый открытый файл открывается в одной вкладке, как бы заменяя предыдущий. Чтобы открыть 2 вкладки с разными файлами, нужно начать редактирование в файле, затем открывать другой, который уже и откроется во второй вкладке. Если нужно просто быстро просмотреть 2-3 разных файла, обивку на стуле приходится менять это приносит некий дискомфорт.

    Поэтому я все так же остановился на Nuclide, правда, подцепив flow, что сильно улучшает автокомплит, добавляет быстрые переходу к компонентам по клику, плюс все фишки с типизацией. Про красивые и удобные запуски проектов в 1 клик пока что приходится забыть.

    Работа с камерой, картой и другими сложными вещами


    Это, пожалуй, наиболее интересный вопрос для всех. Плохая новость — дефолтных компонентов для камеры и карты нету. Нужно использовать нативный код. Хорошая новость — все уже давно сделано до нас:

    • Дико крутые карты под авторством airbnb. Использовал лично, все замечательно работает как на iOS, так и на андроид, так же отлично кастомизируется.
    • Камера уже тоже есть. Хотя, лично не пробовал, небыло необходимости, хотя и любопытно.
    • В геопозицию, благо, умеет из коробки.

    Вообще, уже есть куча рабочих компонентов, нужно просто погуглить. Но можно написать и самому.

    Рабочий процесс


    У react native есть только 1 проблема — андроид проблемы с андроидом. Уж не знаю, проблемы ли это системы или разработчиков, что клали болт на андроид, но с ним вечно какие-то странные косяки.
    Самый странный случай: Date переведенный в строку формата: «YYYY-MM-DD HH:mm:ss» имеет разную длину символов на iOS и android, догадайтесь на какой платформе лишний пробел? Что приводит просто к лютой парное, вот казалось бы, код на чистом js, все работает замечательно на iOS, а на андроиде что-то может пойти не так. Поэтому ВСЕГДА нужно проверят приложение на обеих платформах после ЛЮБОГО изменения кода, никогда не знаешь в какую проблему это может вылиться.

    На самом деле подобная проблема была единична для меня, почему-то криво работает Date на андроиде, а вот momentJS прекрасно. Так что сразу используйте последнее. А вот с версткой проблемы другого характера.
    Во-первых, андроид вообще не умеет в тени, что указываются в стилях. Для него есть отдельный параметр — 'elevation', но только и всего. Цвет тени, радиус, прозрачность — все это проходит мимо андроида.
    Во-вторых, разрешение экранов. У яблофонов просто огромные разрешения, особенно в плюсах, от чего, бывают проблемы, когда выставляешь кнопки с нужными размерами шрифтов, на iOS все смотрится хорошо, на андроиде все слипается — экран маловат будет. Благо, react native дает возможность определить платформу, на которой запустилось приложение, и от этого изменять что-то в коде, например, стили.

    Что касается самого процесса разработки, то тут сложно описать то чувство свободы, которое ты обретаешь, после нативной разработки под android. Android SDK дает нам инструменты, предназначенные для чего-то конкретного, отойти от которых никак нельзя. Вот было придумано, что должна быть активити, в которой подцепляется класс к layout, и хоть что ты делай, а активити быть должна, даже сам гугл с этим ничего поделать не может. Вот дали они нам data binding, и вот используя эту библиотеку активити в 99% случаев используется как костыль, просто чтобы подцепить layout и ViewModel, попутно передав Model, хотя мы в layout'е уже явно указали и model и ViewModel. Абсолютно никакой логики в этом случае тут нету, а активити есть. Для передачи информации нужен Intent, а он без проблем может передавать только простые типы, а если хочется передать объект, то все, здравствуй Parcelable.
    И таких примеров очень много. В случае с react native есть только… JavaScript и все. Ты сам решаешь как сделать тот или иной элемент. Именно поэтому для навигации можно использовать аж 3 разных библиотеки:


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

    Компоненты


    Отдельного упоминания заслуживают компоненты. Для ребят с веба, это привычный инструмент, а вот для нас, ребят с мобилок — это просто серебряная пуля.
    image
    Тут у нас 3 разные кнопки. На самом деле не разные, это один компонент. Понимаете масштаб крутизны компонентов? Тут от слова «совсем» можно забыть про копипасту в верстке. Да, в андроиде есть стили, которые теоретически, должны избавить нас от копипасты. Но ведь они применяются к чистым компонентам. Да, я могу задать стиль button, но что бы сделать кнопку как на картинке выше, одним button в андроиде не обойдешься. Это целый отдельный layout, где будет и TextView и ImageView и у всего этого, а так же у layout будут свои параметры стиля. И все 3 кнопки будут отличаться еще и различным количеством этих компонентов, где-то нету картинок, где-то 2 текста и т.п… Другими словами, сделать все эти 3 кнопки на андроиде не сверстав их 3 раза никак не получится. Ну а как получается это делать на реакте? Тут есть 3 щепотки магии:

    1. Props
    2. Отображение только тех элементов, что существуют
    3. Наложение стилей

    Подробнее обо всем.
    В андроиде мы сначала создаем компонент в layout'е, затем находим его по ID'шнику в активити и передаем какие-то параметры, например, текст меняем. Это работает, если мы заранее знаем что хотим отобразить. В реактиве мы же указываем какой нам создать компонент с НУЖНЫМИ нами параметрами. В чем соль? В props мы можем передавать ВСЕ ЧТО УГОДНО, без каких либо проблем, начиная от простых типов, заканчивая объектами. Допустим, нам нужна еще 1 кнопка, такая же как по середине, только с другой стрелочкой. В андроиде мы бежим рисовать уже 4-ю кнопку, а тут же мы просто передаем через props другую иконку.

    Но бОльшая магия твориться вот тут:

    {true && <Text>Я существую</Text>}
    {false && <Text>Я НЕ существую</Text>} 

    Смысл в том, что так можно не отображать несуществующие объекты. Мы ведь используем JS с динамической типизацией, и ей можно удобно пользоваться для себя, например:
    
    const text = this.props.text;
    {text && <Text> {text} </Text> 

    Если мы передали в props параметр text, то компонент его отрисует, а если не передали, то не отрисует, ибо зачем? Стоит еще раз акцентировать внимание на динамическую типизацию. С текстом все хорошо, текст есть — true, текста нету — false, тоже и с объектами. А вот с числами беда, отправите 0 — JS будет думать что это false… Для чисел лучше более явно проверять тип.
    Начинает доходить логика? Мы делаем компонент, который учитывает все возможные варианты того, что в нем может находится, оборачивая их в конструкцию, что я представил выше.
    И тут может возникнуть другая проблема — слишком большой текст, слишком большая картинка и прочее могут сломать внешний вид компонента. Тут нам на помощь приходит пункт номер 3:

    
    <Text
    style={[styles.defaultStyle, this.props.customStyle]}>
    {this.props.text}
    </Text>

    Стиль мы определяем как массив стилей. Что это значит? Это значит, что если мы НЕ передали в props свой стиль, то компонент будет в дефолтном, который мы определили заранее. Но что, если мы передадим в кастомный стиль 1 параметр, допустим, отступ сверху? И этот компонент будет иметь дефолтный стиль плюс отступ сверху. Смысл в том, что всегда ПОЛНОСТЬЮ применяется дефолтный стиль, только в нем заменяются лишь те параметры, которые мы передаем в кастомном стиле. Т.е. если мы хотим только изменить цвет текста — не беда, размеры, отступы и прочие радости не слетят. А если нам какой-то параметр в стиле не нужен, мы передаем в кастомном стиле этот параметр со значением null.

    Заключение


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

    Самый главный вопрос для кого react native? Да для всех. Делая продукт, нужно держать 2 команды разрабов — для iOS и android. Тут же хватит и одной. Во-первых, это тупо дешевле, нужно в 2 раза меньше людей, а во-вторых, удобно — появился баг, поправил сразу на 2 платформы. И серьезные ребята тоже начали втягиваться. Тут уже не только фейсбук и инстаграмм. Airbnb, walmart, testa, думаю, эти ребята что-то знают)

    Да и потом, проект еще даже не близок к релизу версии 1.0, а им уже заинтересованны многие именитые ребята, которые собираются вместе для развития проекта. У нас есть уникальный шанс сесть не на уезжающий поезд, а на проезд, который еще даже не доехал до станции. Все кто овладел этим инструментом (особенно те, у кого есть опыт нативной разработки под мобилки) еще до массового релиза версии 1.0, будут иметь огромное преимущество перед другими.
    А вы пробовали писать на react native?

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

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

    Подробнее
    Реклама
    Комментарии 16
    • +4
      В vs code для открытия нескольких файлов, можно использовать двойной клик.
      • 0

        Божечки, наконец-то!

        • +2

          Есть настройка "workbench.editor.enablePreview": false, которая отключает режим просмотра.

        • 0
          Примеры выглядят немного притянутыми.
          Например, что мешает в андроиде сделать свой view с нужными стилями?
          • +1
            Ага.

            в Android:

            1. Напиши разметку
            2. Напиши back-класс
            3. Напиши 4 конструктора
            4. Напиши чтение AttributeSet

            в RN:

            1. Напиши разметку
            2. Готово
          • 0
            React Native еще не пробовал, потыкал Ionic (Angular). Тоже вполне удобно. По ощущениям — если писать одно и то же на Java и JS (Ionic), то результат получится один и тот же, а времени и сил нужно меньше. Когда эти кроссплатформенные фреймворки научатся хорошо работать с аппаратной частью — я буду рад :)
            • 0
              Может стрельнуть, а может и нет, в любом случае на данной стадии React Native требует хорошего запаса бубнов…
              • 0
                Из всего кросплатформенного я ставлю именно на реакт. Во-первых, родитель в лице фэйсбука уже достаточно весомый аргумент, а во-вторых, теперь они каждый месяц собираются с другими командами, что бы обсуждать дальнейшее развитие продукта. Вот уже буквально недавно дали возможность создавать проекты вообще без единой строчки нативного кода. Да и уже в таком сыром виде, инструмент уже очень много может.
            • +1
              Во-вторых, разрешение экранов. У яблофонов просто огромные разрешения, особенно в плюсах, от чего, бывают проблемы, когда выставляешь кнопки с нужными размерами шрифтов, на iOS все смотрится хорошо, на андроиде все слипается — экран маловат будет.

              iPhone 7+: 5.5" 1920-by-1080-pixel resolution at 401 ppi
              LG G6: экран 5.7", разрешение 2880x1440 при 565 ppi

              Вот было придумано, что должна быть активити

              И придумана не просто так. Активити отвечает за жизненный цикл.

              Для передачи информации нужен Intent, а он без проблем может передавать только простые типы, а если хочется передать объект, то все, здравствуй Parcelable.

              Потому, что он в том числе используется для IPC. Я реакт пока еще особо не пробовал — он умеет общаться с другими андроид приложениями не через интенты?

              Тут у нас 3 разные кнопки.

              Тут у нас всего одна кнопка, для которой можно сделать
              setCompoundDrawables(@Nullable Drawable left, @Nullable Drawable top, @Nullable Drawable right, @Nullable Drawable bottom)

              А вообще хотелось бы больше примеров реакта, как в первой части статьи :)
              • 0
                Я реакт пока еще особо не пробовал — он умеет общаться с другими андроид приложениями не через интенты?

                Конечно, интенты, дип линки… + Всегда есть возможность написать мост.
              • +2
                Упомянутая камера умеет и бар коды читать, тоже стандартный запрос.

                С навигацией да, всё странно. Сейчас стандартом считается https://reactnavigation.org/
                • 0
                  Самом неожиданным в https://reactnavigation.org/ оказалось отсутствие способа понять внутри экрана, что он ушел на задний план в общем случае. Условно: не реализовано аналогов onResume, onPause.
                  https://github.com/react-community/react-navigation/issues/51 вот тут пол года обсуждают как это должно быть написано: hoc, подписка на ивенты или функции компонента.

                  Есть экспериментальная либа https://github.com/satya164/react-navigation-addons. Сейчас написал костыль над ней, чтобы все работало как привычно.

                  Еще разные navigator-ы по разному управляют компонентами экрана, и у вас не всегда есть контроль над этим. Если у вас на ios табы, на на android drawer, то логика монтирования экранов будет разной: табы грузятся сразу, drawer грузит только текущий экран. В сочетании с первым недостатком писать немного больно.

                  навигация на react-native пишется куда короче в простых случаях, но когда у вас сложная логика при смене экранов, придется писать велосипеды и костыли.
                • 0
                  а чем вам webstorm не угодил?
                  • 0
                    После прочтения статьи осталось ощущение что автор делает только первые шаги?
                    Сам кодю на Qt для мобилок, присматриваюсь к ReactNative, но вот что можно делать в Qt из коробки:
                    — Все сделано на тех самых волшебных компонентах, более того команда Qt постаралась и реализовала кастомные стили.
                    — К любому компоненту (QML) можно прицепить тени (с настройкой цвета, прозрачности, радиуса и пр.), можно компонент развернуть в 3D плоскости.
                    — К любому компоненту можно добавить шейдерный эффект, анимацию в два клика
                    — Довольно простая интеграция с нативным кодом (это если хочется использовать нативные Toast для Андроид, например)
                    — Развитая IDE
                    — Поддержка мультиязычности (в кода вместо строки «строка» пишем tr(«строка») и потом оно само создаст список фраз для перевода)
                    В общем, много удобств и полезностей и не забываем, что под капотом у Qt мотор на С++.

                    Сам пробовал ReactJs, концепция когда компонент хранит и отображает свое состояние показалась не очень удобной, так, если в обычном input редактировать текст, то каждый символ вызывает волну перезаписи свойств этих компонентов что в итоге сильно просаживает производительность.
                    • 0
                      Статья не очень соответствует своему названию.
                      Где тут раскрыт вопрос разработки с колокольни Android? Хотелось бы увидеть какой-то реальный опыт преодоления трудностей и несовершенств ReactNative. А так это просто обзорная статься А-ля «смотрите какой RN классный, но с косяками», коих уже и так полно.
                      • 0
                        Цвет тени

                        Как у тени может быть цвет? Это просто не логично. Тень — участок поверхности или область пространства, менее ярко освещённые по сравнению с прочими, скрытые от прямых лучей света.

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