Prvá aplikácia
vytvorenie aplikácie a jej spustenie, nástroj Yarn, Metro Bundler, základné komponenty rámca React Native, základná štruktúra projektu, syntax JSX, LogBox
Záznam z prednášky
Project Torch Overview
(slide) Na minulej prednáške sme si predstavili rámec na vývoj natívnych mobilných aplikácií React Native a porozprávali sme sa o tom, čo je to chytré zariadenie, aké rozličné typy aplikácií môžeme vytvoriť a ukázali sme si trendy v tejto oblasti na základe výsledkov prieskumu portálu Stack Overflow pre rok 2021.
(slide) Dnes budeme pokračovať. Nainštalujeme si potrebné balíčky pre vývoj aplikácie a začneme vyvíjať aplikáciu Torch. Táto aplikácia bude jednoduchou baterkou na svietenie, kde na svetlo využijeme blesk zadnej kamery/fotoaparátu.
WarmUp
Ešte predtým, ako začneme so samotným vývojom, si potrebujeme pripraviť prostredie pre vývoj. Konkrétne si potrebujeme zabezpečiť tieto veci:
- nainštalovať vývojové prostredie Visual Studio Code
- nainštalovať node.js
- nainštalovať Android SDK
Všetko ostatné si následne nainštalujeme.
Installing React Native
(slide) Na inštaláciu rámca React Native máme niekoľko možností. My budeme pre naše potreby miesto štandardných nástrojov
npm
anpx
používať nástrojyarn
, ktorý je súčasne správcom balíčkov a správcom projektov.Poznámka
Ako som spomínal, nebudeme vytvárať projekto pomocou nástroja/platformy Expo.
Začneme teda prípravou prostredia, kedy si vytvoríme priečinok pre naše projekty a nainštalujeme do neho priamo balíček
react-native
so všetkými jeho závislosťami:$ mkdir projects $ cd projects $ yarn init
Nástroj
yarn
spustí sprievodcu na vytvorenie balíčka, pomocou ktorého vytváraný balíček opíšeme:$ yarn init yarn init v1.22.11 warning ../package.json: No license field question name (projects): question version (1.0.0): question description: Projects for SMART course question entry point (index.js): question repository url: https://kurzy.kpi.fei.tuke.sk/smart question author: mirek question license (MIT): question private: success Saved package.json Done in 20.20s.
Výsledkom bude súbor
package.json
, v ktorom sa nachádzajú metadáta o vytváranom balíčku:$ cat package.json { "name": "projects", "version": "1.0.0", "description": "Projects for SMART course", "main": "index.js", "repository": "https://kurzy.kpi.fei.tuke.sk/smart", "author": "mirek", "license": "MIT" }
Nakoniec už len nainštalujeme balík
react-native
:$ yarn add react-native
Táto operácia bude chvíľu trvať, ale okrem balíčka samozrejme nainštaluje aj všetky závislosti, ako:
- Metro - balíčkovač pre platformu React Native
- Watchman - služba na sledovanie zmien v súborovom systéme
Poznámka
Názov priečinku so spustiteľnými binárkami získame príkazom:
$ yarn bin /path/to/projects/node_modules/.bin
Jeho obsah následne zobrazíme príkazom
ls
:$ ls node_modules/.bin atob jetifier-standalone metro-inspector-proxy sane browserslist jetify metro-symbolicate semver envinfo jsesc mime uglifyjs esparse json5 mkdirp uuid esvalidate js-yaml parser watch image-size logkitty react-native which is-ci loose-envify regjsparser jetifier metro rimraf
Create a project
Keď máme nainštalovaný rámec
react-native
, projekt našej aplikácie vytvoríme nasledovne:$ yarn react-native init --title Torch torch
Poznámka
Príkaz
init
má samozrejme niekoľko ďalších možností, ktoré je možné použiť. Ich zoznam si môžete vypísať pomocou prepínača--help
:$ yarn react-native init --help
Napríklad môžete pre vývoj použiť šablónu projektu s podporou typescript-u:
$ yarn react-native init torch --title Torch --template react-native-template-typescript
Vytvorenie projektu opäť zaberie nejaký čas, kedy dôjde k nainštalovaniu potrebných balíčkov a vytvorenie projektu na základe zvolenej šablóny. Po jeho vytvorení sa zobrazí krátky pomocník, ktorý hovorí o tom, ako spustiť projekt:
Run instructions for Android: • Have an Android emulator running (quickest way to get started), or a device connected. • cd "/path/to/projects/torch" && npx react-native run-android
A sme pripravení zostaviť aplikáciu ;)
Metro Bundler
Vojdem teda do priečinku
torch/
a ešte predtým, ako spustím zostavenie aplikácie, zadám príkazyarn start
:$ yarn start
Upozornenie
Ak sa vám po spustení zobrazí chyba
Error: ENOSPC: System limit for number of file watchers reached, watch '/path/to/file'
potrebujete vo vašom systéme navýšiť príslušný limit. To docielite príkazom:
$ echo fs.inotify.max_user_watches=524288 | \ sudo tee -a /etc/sysctl.conf && sudo sysctl -p
(slide) Miesto aplikácie sa však spustí Metro Bundler. Metro Bundler je JavaScript-ový balič (z angl. bundler) pre React Native. Je zodpovedný za zabalenie súborov celej aplikácie (kód, závislosti, asset-y) do jedného súboru.
(slide) Ak sa venujete tvorbe JS aplikácií, s termínom Bundler ste sa už stretli. S najväčšou pravdepodobnosťou používate na tento účel Webpack, ale možno používate už aj vychádzajúcu hviezdu v tejto oblasti Snowpack.
Na čo však JS Bundler slúži? Zjednodušene spojí všetky JS moduly do jedného, všetky CSS štýly do jedného, proste z viacerých súborov vytvorí jeden (balík).
Metro Bundler teda bude sledovať zmeny v našom kóde (pomocou Watchman-a) a jeho úlohou bude zostaviť výsledný balík reprezentujúci aplikáciu a následne nám pomôže dostať ho na cieľovú platformu, ktorá je v našom prípade Android zariadenie.
Running Your Application
Running on Android device/emulator
Ak v rozhraní nástroja Metro Bundler klikneme na položku Run on Android device/emulator alebo v príkazovom riadku stlačíme kláves
a
, spustí sa aplikácia v na platforme Android .To, či sa spustí na zariadení alebo v emulátore, záleží od viacerých faktorov:
ak máte k počítaču pripojené zariadenie so systémom Android a toto zariadenie má zapnutý Režim pre vývojárov, spustí sa aplikácia na ňom
ak zariadenie k počítaču pripojené nemáte, ale máte nainštalovaný v počítači emulátor so systémom Android, automaticky sa spustí tento emulátor
Prvé spustenie v každom prípade trvá dlhšie, nakoľko najprv sa nainštaluje klientska aplikácia Expo. Až potom dôjde k nahratiu vytvorenej aplikácie.
Project Structure
Pozrime sa však najprv na to, ako vyzerá štruktúra vytvoreného projektu:
$ tree -L 1 . ├── android/ ├── App.js ├── app.json ├── babel.config.js ├── index.js ├── ios/ ├── metro.config.js ├── node_modules/ ├── package.json ├── __tests__/ └── yarn.lock 4 directories, 7 files
Význam jednotlivých súborov a priečinkov je nasledovný:
android/
aios/
-node_modules
,package.json
ayarn.lock
-App.js
- predstavuje základný komponentapp.json
- konfiguračný súbor aplikácieindex.js
-babel.config.js
-metro.config.js
- konfiguračný súbor pre Metro__tests__/
-
Fast Refresh
Jednou z výhod rámca React Native je “blesková” aktualizácia vykonaných zmien. Ak totiž vykonáte vo svojom kóde zmenu a uložíte ju, tá sa okamžite dostane na všetky výstupné zariadenia. Nepotrebujete teda čakať na preklad a prenos novej binárky na cieľové zariadenie, ako je to v prípade natívneho vývoja.
Túto vlastnosť si vieme vyskúšať v komponente
App
, ktorý sa nachádza v súboreApp.js
. Stačí, ak upravíte text v elemente<Text>
a súbor uložíte. Zmena sa okamžite dostane na všetky zariadenia, kde ste vašu aplikáciu vypublikovali pomocou nástroja Metro Bundler.
React Native vs React
(slide) Ak chceme zvládnuť prácu v rámci React Native, nemôžeme zabudnúť na rámec React, na ktorom je React Native postavený, a na ktorom je závislý. Obecne môžeme povedať, že rámec React Native sa používa na tvorbu (nie len) mobilných aplikácií pomocou React-u a schopností/možností natívnej platformy. Túto závislosť si môžete všimnúť aj v súbore
App.js
, kde sa React importuje riadkom:import React from 'react';
Pre zvládnutie rámca React Native je teda dobré poznať aspoň základy rámca React.
(slide) Takže - čo je React? React je knižnica pre JavaScript na tvorbu používateľských rozhraní. Tie sa vytvárajú pomocou malých izolovaných častí, ktoré sa nazývajú komponenty.
Komponenty je možné navzájom prepájať, čím je možné vytvárať komplexné používateľské rozhrania. Toto prepojenie je možné vizualizovať pomocou stromu, v ktorom existuje jeden koreňový komponent a každý ďalší komponent sa stáva jeho samostatnou vetvou. Každá ďalšia vetva môže mať samozrejme ďalšie podvetvy. Príklad takéhoto stromu komponentov (z angl. component tree) sa nachádza na nasledujúcom obrázku:
Components
Komponenty sú základným stavebným prvkom týchto rámcov. Pozrime sa teda zblízka na to, čo je vlastne komponent.
Pre jednoduchosť nahradím ukážkovú aplikáciu, ktorá bola automagicky vytvorená, za jednoduchšiu. Vytvorím jeden komponent
App
, ktorý bude súčasne aj koreňovým komponentom aplikácie:import React from 'react'; import {Text, View, StyleSheet} from 'react-native'; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#fff', , }; }) export default function App() { return ( <View style={styles.container}> <Text>Hello, world!</Text> </View> ; ) }
Komponent je teda definovaný ako funkcia. Čokoľvek, čo táto funkcia vráti, je vykreslené ako React element, ktorý definuje, čo bude viditeľné na obrazovke zariadenia. To znamená, že čokoľvek, čo vidíme na obrazovke, je nejakým prípadom komponentu. Definujeme vlastne pohľad (view) komponentu.
Obecne je každý komponent definovaný svojim stavom a vlastnosťami. O nich si však porozprávame trochu neskôr.
Views
(slide) Pri vývoji aplikácií pre Android alebo iOS sú pohľady (views) základným stavebným blokom pre tvorbu používateľského rozhrania. Obecne sa jedná o elementy obdĺžnikového tvaru, pomocou ktorých vieme zobrazovať text, obrázky, vedia reagovať na vstup od používateľa.
Pohľad (view) je vlastne všetko, čo je možné zobraziť na obrazovke zariadenia. Niektoré pohľady môžu obsahovať aj iné pohľady.
(slide) Rámec React Native obsahuje generické (core) komponenty (resp. pohľady), pomocou ktorých je možné vyskladať ľubovoľné používateľské rozhranie pre všetky podporované platformy. Následne pri spustení rovnakého kódu na konkrétnej platforme sú tieto pohľady nahradené natívnymi komponentami (resp. pohľadmi). Túto situáciu ilustruje nasledujúci obrázok.
(slide) React Native má mnoho Core komponentov. Ich kompletný zoznam nájdete v dokumentácii API. Najčastejšie však budete pracovať s komponentami, ktoré sú uvedené v nasledujúcej tabuľke.
Prehľad najčastejších komponentov React Native [@y1] React Native UI Component Android View iOS View Web Analog Description <View>
<ViewGroup>
<UIView>
A non-scrollling <div>
A container that supports layout with flexbox, style, some touch handling, and accessibility controls <Text>
<TextView>
<UITextView>
<p>
Displays, styles, and nests strings of text and even handles touch events <Image>
<ImageView>
<UIImageView>
<img>
Displays different types of images <ScrollView>
<ScrollView>
<UIScrollView>
<div>
A generic scrolling container that can contain multiple components and views <TextInput>
<EditText>
<UITextField>
<input type="text">
Allows the user to enter text
JSX
(slide) Keď sa však pozrieme bližšie na to, čo funkcia v skutočnosti vracia, nie je to ani reťazec a nie je to ani HTML. React totiž používa syntax JSX (JavaScript XML), čo je XML/HTML rozšírenie pre kód jazyka JavaScript. React nie je na technológii JSX závislý, ale jeho použitím je tvorba komponentov jednoduchšia, prehľadnejšia a hlavne prirodzenejšia. Za syntaxou JSX stojí rovnako spoločnosť Facebook.
Príklad jednoduchého
Hello, world!
komponentu môže vyzerať takto:function HelloWorld() { return <Text>Hello, world!</Text>; }
Aby React (a vlastne JavaScript) rozumel JSX, je potrebné použiť transpiler Babel, ktorý dokáže preložiť tento značkovací jazyk do jazyka JavaScript. Ten okrem toho pozná aj všetky novinky, ktoré priniesol ES6 (ECMAScript 2015).
Button Component
Do UI našej aplikácie potrebujeme pridať tlačidlo, pomocou ktorého budeme baterku ovládať. Na to použijeme komponent
Button
, ktorý sa podľa potreby vyrenderuje na každej platforme.Komponent bude vyzerať nasledovne:
<Button onPress={onPressButton} title="Turn On" />
Ako je možné vidieť, komponent tlačidla má dva povinné atribúty:
title
- text, ktorý sa na tlačidle zobrazíonPress
- funkcia, ktorá bude zavolaná po stlačení tlačidla.
Z komponentu
App
môžeme vypustiť komponent<StatusBar>
a pridáme do neho komponent<Button>
:export default function App() { return ( <View style={styles.container}> <Text>Hello, world!</Text> <Button ={function () { onPressconsole.log("Button was pressed"); }}="Turn On" title/> </View> ; ) }
Ak tlačidlo stlačíme, v konzole Metro Bundler-a alebo v nástroji Visual Studio Code uvidíme vypísaný text.
Poznámka
Vypisovať pomocné texty do konzoly samozrejme nie je nutné len obecnou funkciou
console.log()
. K dispozícii máme niekoľko úrovní logovacích správ, ktoré Metro bude aj adekvátne farebne od seba odlišovať:console.debug('Debug Log Level.'); console.info('Info Log Level.'); console.warn('Warning Log Level.'); console.error('Error Log Level.');
Chyby a upozornenia sú okrem konzoly Metra zobrazované aj pomocou tzv. on-screen notifikácií so žltým alebo červeným odznakom zobrazované na obrazovke zariadenia.
Po kliknutí na tento odznak sa zobrazia detaily chyby alebo upozornenia v LogBox okne.
Conclusion
Dnes sme teda vytvorili kostru aplikácie baterka. Popri tom sme sa zoznámili s niektorými komponentmi rámca React Native a predstavili sme si ich vlastnosti.
Nabudúce budeme pokračovať a pokúsime sa rozsvietiť blesk fotoaparátu vo vašom zariadení. Samozrejme len v prípade, že ho zariadenie obsahuje vo svojej výbave.