Kuinka rakensin ensimmäisen React Native -sovelluksen ensimmäiselle freelance-asiakkaalleni

https://www.pexels.com/@nietjuh

Käynnistin äskettäin ensimmäisen natiivi mobiilisovelluksen, joka on rakennettu React Native -sovelluksen avulla. Kuten tapahtuu, se oli myös ensimmäinen sovellus, jonka olen rakentanut asiakkaalle freelancer-kehittäjänä. Tässä on kova ajo, aina reagoivasta aloitteesta sovelluskaupan julkaisuun.

Sisällysluettelo

  1. Miksi freelance?
  2. Miksi reagoida alkuperäiskansoihin?
  3. Sovelluksen tiedot
  4. Opi parhaalta
  5. Kehitysympäristö
  6. suunnistus
  7. Aloitusruutu
  8. Valtion hallinto
  9. istunnot
  10. Listat
  11. kuvat
  12. Aika
  13. Muokatut fontit ja kuvakkeet
  14. CI / CD ja seuranta
  15. Tuen lisääminen Androidille
  16. Koska Apple
  17. Yhteenveto

Miksi freelance?

Viime toukokuussa kompasin tätä jännittävää freelance-tilaisuutta. Tuolloin työskentelin Tukholmassa toimivan startup-yrityksen full stack -verkkosuunnittelijana. Se oli ensimmäinen dev-työni, ja laskusin sen tuskin vuotta aikaisemmin (josta voit lukea lisää tässä artikkelissa).

Kesä lähestyi nopeasti, ja muuten melko korkea työvauhti hidastui päivä päivältä. Yhden viikon aikana, kun tuoteryhmän kiertävä teknisen tuen velvollisuus oli minun, tunsin olevani vähän tylsistynyt ja turhautunut joihinkin virheisiin, joille minulle osoitettiin.

Isä otti minuun yhteyttä tässä synkkässä ilmapiirissä aikomuksestaan ​​rakentaa mobiilisovellus yrityksen asiakkailleen. Vaikka hän tiesi työni pitävän minut kiireisenä eikä odottanut kokopäiväistä sitoutumista, hän kysyi, haluanko olla osa hanketta neuvoa-antavassa roolissa. Hieman älyllisesti nälkäinen sanoin kyllä. Vaikka se ei ollut minun alkuperäinen aikomukseni, tämä neuvoa-antava rooli johti lopulta siihen, että aloitin sovelluksen kehittämisen pääkehittäjänä.

Nyt voit kysyä itseltäsi - miksi edes yritetään päästä mobiilisovellustilaan vain vuoden ajan ammattimaisesta web-kehityskokemuksesta? Eikö olisi järkevämpää jatkaa erikoistumista tälle alalle lisäämällä muutaman vuoden kokemus ansioluetteloosi?

Ehdottomasti se olisi. Koska olen kuitenkin toivoton yleinen edustaja, sitouduin useita vuosia sitten tekemään urapäätöksiä, jotka eivät perustu urastrategiaan, vaan pikemminkin siihen, mikä tekee minut onnelliseksi. Toisin sanoen: Ansioluetteloni on jo junan hylky, joka ei todennäköisesti voinut saada hajanaisempaa ja epäjohdonmukaisempaa.

Urastrategia ja työelämän onnellisuus eivät tietenkään välttämättä sulje toisiaan pois. Itse asiassa olin erittäin tyytyväinen entiseen työhöni ja työnantajani. Satusin juuri löytämään toisen projektin, josta tunsin entistä intohimoisemmin.

Joten mikä teki tästä projektista mielenkiintoisen? Vieläkin mielenkiintoisempaa kuin työskennellä sellaisen hyperkasvutuoteen kanssa, jota tuhannet yritykset käyttävät joukkueessa, jonka joukossa olen tavannut upeimpia ihmisiä? Kolme sanaa: vapaus, haaste ja itsensä kehittäminen.

Miksi reagoida alkuperäiskansoihin?

Kun liittyin projektiin, asiakasni oli jo saanut muutaman tarjouksen joiltakin paikallisilta digitaalitoimistoilta. Ennen kuin edes harkitsin oman sovelluksen rakentamista, minua pyydettiin arvioimaan ne ystävällisenä palveluna. Ja minä vain hämmästyin ehdotusten heikosta laadusta.

Yksi heistä oli lähettänyt joitain malleja, jotka olivat todella huolimattomia eivätkä olleet lainkaan asiakkaan verkkosivustolla esitetyn brändin mukaisia. Toinen virasto ehdotti naurettavaa hintaa vielä naurettavammalla toistuvilla maksuilla. Ja kolmasosa ei edes näyttänyt edes tekevän mitään sävelkorkeutta. Ja heillä kaikilla oli yksi asia: että he halusivat rakentaa sovelluksen hybridikehys Cordovan kanssa.

Ja se ei ollut kaikki. Vaikka Cordova on täysin ilmainen ja avoimen lähdekoodin, yksi heistä oli jopa yrittänyt piilottaa tosiasian, että tämä oli heidän käyttämänsä tekniikka. Sen sijaan he mainostivat "omaa" sisäistä mobiilisovellusalustaa - näennäisesti vain ohutta kerrosta Cordovan ympärillä - perustellakseen lukituksen antamisen heille yksinoikeudella sovelluksen ylläpidon oikeudet ja tekemällä mahdollisesta tulevasta luovutuksesta monimutkaista ja kallista. Heikkolaatuiset ehdotukset.

Nyt en pidä huolestuneena hybridikehyksiä. Käytän heidän kanssaan rakennettuja sovelluksia koko ajan. Gmail, Slack, Atom ja Figma muutamia mainitakseni. Mutta tuolloin olin kuullut React Nativesta jo jonkin aikaa. Kuinka se sallii rakentaa eri käyttöympäristöjen mobiilisovelluksia Javascriptin avulla - se ei ollut hybridi!

Mitä nyt? Olisiko iOS ja Android jonkin verran salaperäisesti tukenut natiivissovellusten kirjoittamista Javascriptiin? Koska tarkistin viimeksi, iOS-sovellukset oli rakennettava Objective-C: llä tai Swiftillä ja Android-sovellukset Javailla tai Kotlinilla.

Ei tietenkään. Joten miten React Native -sovelluksia voidaan kutsua todellisiksi natiivisovelluksiksi? Lyhyt vastaus: Sovellusliittymät. Tämän hankkiminen kesti kauemmin kuin uskallan myöntää, mutta tapa, jolla React Native -sovellukset voivat toimia älypuhelimessa natiivisti, ei ole ajamalla Javascriptiä, eikä kääntämällä Javascriptiä alkuperäiseen koodiin, vaan tekemällä pyyntöjä sovellusliittymille, jotka tarjoavat alkuperäisiä komponentteja Objective-C: ssä iPhonessa ja Java-laitteissa Androidissa.

Jos haluat tietää enemmän React Nativen perusteista, suosittelen todella tätä superpedagogista Quora-vastausta, tätä hämmästyttävän Parashuram N: n React Conf -puhetta ja RN: n alkuperäistä paljastamista maailmalle.

Vaikka en tiennyt tuolloin tätä salaa React Native -taikaisen tempun takana, tiesin, että kyseessä oli itse asiassa natiivikoodi - mikä oli myös pääasiallinen perusteeni olla käyttämättä mitään virastojen ehdottamaa Cordova-ratkaisua. Arvelin, että jos he halusivat mobiilisovelluksen, heidän tulisi rakentaa alkuperäinen sovellus. Ja jos he haluaisivat HTML / CSS / JS-sovelluksen, rahansa käytettäisiin paremmin yksinkertaisesti parantamalla verkkosovelluksensa mobiilikokemusta.

Kun jaoin tämän asiakkaan kanssa, he kysyivät minulta tuntuiko joku, joka pystyisi rakentamaan tällaisen sovelluksen. Sanoin heille, etten tehnyt. He kysyivät, voinko tehdä sen. Sanoin heille, etten voisi. Silti siemenet oli istutettu, enkä vain pystynyt estämään itseäni hiipimästä React Nativen kanssa heidän sovellusmääritystensä perusteella.

Ja ennen kuin tiesin sen, heidän sovellukselleen oli jo perusta. Joten jotenkin, vain muutaman viikon kuluttua keskustelusta sovimme, että rakennan sovelluksen heille.

Sovelluksen tiedot

Ennen kuin harkitsemme teknisempiä yksityiskohtia, lyhyt kuvaus siitä, minkä tyyppisillä sovelluksilla me täällä käsittelemme, näyttää olevan paikoillaan.

Asiakas on Tukholmassa toimiva yritys, joka ylläpitää työtiloja. Toisin sanoen, työtilahotellit yrityksille. Heillä on tällä hetkellä noin 10 aktiivista tilaa, joista noin 400 yritystä, joissa on noin 1 400 työntekijää, vuokraa toimistotilaa. Nämä vuokralaiset ovat sovelluksen kohderyhmä.

Aula yhdessä asiakkaan työtovereiden tiloissa

Projektipäällikön kanssa edestakaisin käytyjen keskustelujen jälkeen kiteytyi muutama sovelluskuvaus:

  • Sisäänkirjautumisen / kirjautumisen todennus ja salasanan nollaus. Huomaa: järjestelmänvalvojat ovat luoneet kaikki käyttäjätilit, joten ilmoittautuminen ei ole mahdollista sovelluksessa. Siksi, jos päätät ladata sovelluksen, et voi periaatteessa tehdä mitään sen kanssa
  • Katselee ja muokkaa käyttäjäprofiilia, mukaan lukien nimi, sähköposti, salasana ja avatar-kuva.
  • Push-ilmoitukset.
  • Kotikohde, josta käyttäjät voivat lukea viimeaikaisista tapahtumista yrityksen ympäristössä yleensä ja erityisesti kotisi työpaikasta.
  • Yhteisön määränpää, jossa käyttäjät voivat selata erilaisia ​​yhteisötiloja, ottaa yhteyttä kunkin tilan sivuston ylläpitäjään ja nähdä muita kotimaisia ​​yrityksiä.
  • Konferenssikohde, jossa käyttäjät voivat varata kokoushuoneita ja hallita varauksiaan.
  • Valintakohde, josta käyttäjät voivat päästä yksinoikeudella jäsen alennuksia ja tarjouksia.
  • Luo ensin iOS-versio ja lisää sitten Android-tuki.
  • Taustaohjelman järjestelmänvalvojan verkkosovellus RN-sovelluksen sisällön hallintaan. Vaikka keskityn tässä tekstissä olevaan etuosaan, voi olla aiheellista tietää, että se on rakennettu Ruby on Rails-, Postgres- ja Heroku-sovelluksiin.

Kuten voitte kertoa, se on melko ohut ominaisuuskokonaisuus. Mikä on tarkalleen mitä haluat ensimmäiselle sovelluksellesi uudella tekniikalla. Jos haluat tietää, miten lopputulos osoittautui (ja onko loppuosa tästä tekstistä aikaa vai ei), tässä on yleiskatsaus 1.0-versioon:

Olet yhä täällä? Hienoa, siirrytään eteenpäin.

Opi parhaalta

Joten kuvittele, että olet luvannut ystävälle rakentaa heille talon. Mutta sinulla ei ole aavistustakaan kuinka rakentaa talo. Tuskin edes mistä aloittaa. Mikä on ensimmäinen asia, jonka teit?

Löydät itsesi kirvesmiehen.

Joten juuri sitä yritin tehdä. Ja löysin jättipotin. Tutkittuaani vain muutaman tunnin React Native -oppimisresursseja, löysin Youtubesta 13-osaisen videokurssin Harvardista (täysin ilmainen). Jokainen luento syventyen omaan aiheeseensa 90–120 minuutin välillä. Joten yhteensä noin 23 tuntia korkealaatuista materiaalia.

Heti aloitin videoluentojen kuluttamisen ikään kuin hallussaan. Ja muutaman viikon koodauksen jälkeen öisin ja viikonloppuisin, olen suorittanut kurssin ja asettanut itselleni melko kunnollisen sovelluspohjan.

Jälkikäteen se on epäilemättä yksi parhaimmista oppimisresursseista, jonka olen löytänyt, kaikki luokat. Pakatulla ja aina asiaankuuluvalla opetussuunnitelmalla oli ehdottomasti iso osa, mutta opettaja Jordan Hayashi oli ehdottomasti suuri voitto täällä. Kuvailisin hänen opetustyyliään nopeaksi, erittäin käytännölliseksi ja suoraan pisteeseen. Ei aikaa hukkaan huonoille vitseille ja häiritseville henkilökohtaisille anekdooteille. Toisin kuin sinun todella ...

Joka tapauksessa jokainen luento näytti aina puristavan tietyn määrän tietoa, joka vie suurimman osan muista opettajista ainakin kahdesti. Toisin sanoen tyyli, joka on hyvin samanlainen kuin Harvard CS50 -opettaja David J Malan.

Joten jos etsit lähtökohtaa ensimmäiselle RN-sovelluksellesi, se olisi suositukseni numero 1. Yksi varoitus kuitenkin: Kurssilla Jordan käyttää Expo-työkaluketjua, joka on loistava työkalu useimpiin yksinkertaisiin sovelluksiin, koska se tekee paljon typerää rakeista työtä sinulle. Mutta jos sinä, kuten minä, rakennamme perustaa sille, josta voi tulla aika iso ja monimutkainen sovellus ennemmin kuin myöhemmin, jossa arvostat koko määritysvapautta, reagointi-natiivi init voi olla sopivampi ratkaisu.

Toiseksi paras oppimateriaali, johon minulla oli pääsy, oli itse asiassa kollegani. Onnekas sattuma, olimme juuri aloittamassa React Native -projektissa yrityksessä, jossa työskentelin vasta muutama kuukausi sitten. Vaikka en ollut itse projektissa, oppin tonni puhumalla vain projektin kavereiden kanssa ja tarkistamalla heidän PR: nsä.

Nyt kun kaikki asiayhteyteen liittyvät asiat on järjestetty, voimme lopulta siirtyä teknisempiin asioihin!

Kehitysympäristö

Saatuaan sovellussäätiön perustamiseen react-native-init-sovelluksen avulla yksi ensimmäisistä haasteista oli saada mukavuus uuteen kehitysympäristöön.

Jos olet kotoisin tavallisesta verkkokehitysympäristöstä, monet asiat pysyvät ennallaan. Minulle sisälsi Atomin pitäminen tekstieditorina, iTerm päätelaitteena ja GitUp git-käyttöliittymänä (siellä oleville uriseville Vimin käyttäjille: vihaajat vihaavat). Mutta muu kuin React Native, vaati muutamia lisäyksiä tavalliseen työnkulkuoni.

Nauti viihtyisästä esimerkiksi iOS-simulaattorilla. Suorittamalla komentoriviltä ”react-native run-ios” kuulostaa petolliselta yksinkertaiselta, alussa se riitti harvoin simulaattorin käyttöönottoon. Koska uusia npm-paketteja lisättiin projektiin melkein päivittäin (ja myöhemmin myös melkoisesti muutamissa alkuperäisissä CocoaPod-moduuleissa), minun piti tutustua paremmin silloin, kun piti vaikeasta rituaalista tyhjentää vartija, poistaa kiireinen välimuisti, poistaa node_modules-hakemisto, asentamalla kaikki solmumoduulit uudelleen ja palauttamalla Metro Bundler -välimuisti. Seuraava komento tekee kaiken tämän puolestasi:

vartija katsella-del-kaikki && rm-rf tmp / kiire-kartta-reagoi-alkuperäis-pakkaaja && rm -rf node_modules && lanka & & npm start - reset-cache

9 kertaa 10: stä, että tanssi riittäisi saamaan simulaattorin uudelleen käyntiin. Ja toisinaan se vaatii syvälle poistumista erilaisista GitHub-aiheista ja Stackoverflow-ketjuista.

Joidenkin muiden kipujen syynä oli se, että ajattelin pitkään, että Xcoden avaaminen vaaditaan tiettyjen asioiden saavuttamiseksi. Ja usko minua, haluat viettää mahdollisimman vähän aikaa IDE: n kauhuhuoneessa (lisää siitä myöhemmin).

Kuten käsketään simulaattoria ajamaan tiettyä iPhone-versiota. Jos joku olisi kertonut minulle, että alla oleva rivi teki täsmälleen minulle, suoraan komentoriviltä, ​​olisin todennäköisesti ollut hieman onnellisempi henkilö näiden ensimmäisten kuukausien aikana.

react-native run-ios --simulator = 'iPhone X'

Toinen esimerkki olisi 3-vaiheinen raketti, jota vaaditaan siirtyessäsi vapautustilasta (sovelluksen käyttöönottamiseksi App Storeen tai johonkin CI-kohteeseen, kuten Visual Studio App Center tai Firebase), virheenkorjaustilaan (dev-tila). Ehkä monille ilmeinen, nämä muutokset voidaan tehdä myös suoraan valitsemastasi tekstieditorista. Joka tapauksessa vain kaksi pientä asiaa, joilla oli yllättävän suuri vaikutus työhöni, kun työskentelin dev-tilassa.

Viimeiseksi kesti jonkin aikaa tottuaakseen jatkuvasti hyppäämään eri MacOS-sovellusten välillä tehdä asioita, jotka normaalisti tein Chromessa työskennellessään verkkosovellusten kanssa.

Tarkistaakseni Javascript-konsolilokiini ja HTML / CSS-tulosteeni tyylivirheiden suhteen, käännyin React Native Debugger -sovelluksen puoleen. Ja seurataksesi sovelluksen tilaa, lähetettyjä toimia ja API-pyyntöjä / vastauksia käytin Reactotronia. Vaikka löysin molemmat näistä sovelluksista erittäin hyödyllisiä, en voinut ohittaa vastaavaa Ember.js-työnkulkua, jossa pystyin tekemään kaikki nämä asiat samassa paikassa, jossa sovellukseni tosiasiallisesti toimi (Ember Inspector Chromen avulla kytkeä).

suunnistus

Navigointi / reititys on ilmeisesti ollut melko vaikea ratkaista ongelma React Native -sovelluksessa. Neljän vuoden sisällä on tarjolla paljon erilaisia ​​ratkaisuja, mutta silti ei ole selvää yksimielisyyttä siitä, mikä on paras. Päätin siirtyä reagointi-navigointiin, mutta lähinnä siitä johtuen, että ratkaisuna käytettiin sekä Harvardin kurssilla että projektissa, jonka kollegani työskentelivät.

Jos olisin kuitenkin ottanut aikaa tehdä asianmukaista tutkimusta, olen voinut tehdä seuraavat havainnot:

  • Reagointi-navigointirepo-tapahtumassa on ~ 15 000 tähteä ja 86 avointa numeroa. Se on täysin Javascript-pohjainen ja sisältää myös kaikkein perusteellisimman dokumentoinnin kaikista näkemistäni navigointiratkaisuista.
  • Reagoi-natiivi-navigointi-repolla on ~ 10 000 tähteä ja 162 avointa numeroa. Huomaa myös, että se ei ole täysin Javascript-pohjainen (ts. Vaatii natiivitiedostojen muokkaamista).
  • Reaktorireitittimen repolla on ~ 35 000 tähteä ja 36 avointa numeroa. Nämä luvut eivät kuitenkaan ole oikeasti verrattavissa muihin, koska repo sisältää myös React.js: n reitityspaketit.
  • Alkuperäisessä navigointirepossa on ~ 3 000 tähteä ja 55 avointa numeroa. Sitä, että tämä ratkaisu on edelleen beeta, ei täysin Javascript-pohjainen ja Airbnb ylläpitää, tulisi kuitenkin harkita vakavasti ennen kuin investoidaan siihen paljon aikaa (Airbnb päätti auringonlaskun React Native).

Edellä esitetyn perusteella olisin todennäköisesti edelleen valinnut reagointi-navigoinnin, koska minulla ei olisi ollut aikaa testata niitä kaikkia, kuten esimerkiksi Kurtis Kemple MLS: llä teki. Viimeinkin, kuten hän selittää puheessaan, navigointiratkaisun valitseminen ei oikeastaan ​​ole kysymys siitä, mikä ratkaisu on paras, samoin kuin kysymys siitä, mikä ratkaisu sopii parhaiten sinun tarpeisiisi.

Kun olen työskennellyt react-navigoinnin kanssa noin 9 kuukautta, minun on sanottava, että minulla ei oikeastaan ​​ole paljon valitusta. Koska tärkein viitekohta oli Ember.js: ssä käytetty router.js-kirjasto, se oli täysin uusi reitityskokemus.

React-navigoinnin kolmen päätyypin navigaattorien oppiminen oli helppoa (StackNavigator, TabNavigator ja DrawerNavigator). Vaikea osa oli ymmärtää, kuinka navigaattorit tulisi asettaa sisäkkäin toisiinsa saadakseen haluttu käyttäjävirta.

Esimerkiksi se, että DrawerNavigatorin piti olla navigointijuuressa (yksi askel tärkeimmän TabNavigaationi yläpuolella), ei ollut minulle lainkaan selvää. Jos tätä on vaikea kuvata, tässä on DrawerNavigator toiminnassa (todellisuudessa paljon sujuvampaa kuin gifissä):

react-navigation's DrawerNavigator toiminnassa

Kuten voitte nähdä, halusin sivupalkin, joka voitaisiin avata peukalon pyyhkäisyllä mistä tahansa sovelluksen kohdasta.

Sivupalkkina näyttäminen on enemmän sovelluksen toissijainen komponentti verrattuna alaosan päävälilevyyn, ensimmäinen intuitioini tässä oli, että DrawerNavigator tulisi sijoittaa reittipuun BottomTabNavigator-keskuksen alapuolelle tai samansuuntaisesti (katso kuva alla) .

Kun paukkoin päätäni seinää vasten yrittäessäni pakottaa puristamaan sivupalkkia sinne, huomasin, että reagointi-navigointitapa olisi todella asettaa DrawerNavigator askeleen BottomTabNavigatorin yläpuolelle, ts. Reittipuun juurelle. Toivottavasti tämä pelastaa jonkun siellä melko paljon tunteja, jotka vietin asiakirjoissa ja GitHub -julkaisuissa saadakseni tämän käsityksen.

Tässä on toinen esimerkki DrawerNavigator -sovelluksen juuresta:

Sovelluksen 1.0-version lopullinen navigointipuu

Yksi kysymys, jonka voit kysyä itseltäsi, on: miksi sekä StackNavigator että TabNavigator sekä yhteisölle että konferenssille? Miksi et vain ohita pinokerrosta ja siirry suoraan välilehdille?

No, koska halusin otsikon kummankin TabNavigatorin päälle. Nämä kaverit:

Jälleen intuitio ja reagoiva navigointitapa tehdä asioita eroavat toisistaan. Koska createMaterialTopTabNavigator on oltava melko tavallinen navigointikomponentti, arvelin, että sillä pitäisi olla yksinkertainen sisäänrakennettu otsikkokokoonpano navigointivalinnoissa. Osoittautuu, että se ei ole, minkä vuoksi pakotin käyttämään väliin StackNavigatoria ja lisäämään siten uuden infrastruktuurin monimutkaisuuskerroksen puhtaasti pinnallisiin tarkoituksiin.

Tämä virhe reagointi-navigoinnissa aiheutti minulle myös vakavampia ongelmia. Nimittäin otsikkokuvien saaminen romahtamaan / katoamaan, kun käyttäjä vierittää alaspäin missä tahansa kahdesta FlatListasta. Koska Koti- ja Valinta-otsikot esitetään samassa StackNavigatorissa kuin niiden luettelot, tämä voidaan tässä ratkaista helposti antamalla otsikon vierittää ylöspäin muun luettelon kanssa.

Mutta yhteisön ja konferenssin kanssa - koska otsikot on hahmoteltu StackNavigatorsissa ja TabNavigators-luettelot askeleen niiden alapuolella puussa - en löytänyt keinoa soveltaa samaa ratkaisua niihin. Siksi minulla on tämä tuskallinen epäsymmetria:

Vieritys TabNavigatorissa vs. StackNavigator

Nyt tämä ei ehkä ilmene ongelmana yllä olevassa simulaattorissa käynnissä olevassa iPhone X: ssä, mutta pienemmissä näytöissä kyseinen otsikko saattaa viedä noin 20% arvokkaasta näytön pinta-alasta. Jos jollain on idea siitä, miten tämän kiertää, olen kaikki korvat!

Sama TabNavigator-aihe aiheutti ongelman myös yhteisössä. Kuten alla on osoitettu, halusin laittaa toisen TabNavigator -sovelluksen Coworking Spaces -välilehteen, jotta kolme ylävälilehteä, tiedot, jäsenet ja yhteyshenkilöt näkyvät gifin oikealla puolella.

Koska TabNavigator teki todella vaikeaksi laittaa kuvaesityksen sen päälle lisäämättä paljon monimutkaisuutta, joka aiheutti kaikenlaisia ​​muita navigointipäänsärkyjä (liittyi pääasiassa navigointiparameihin), jouduin turvautumaan JS-pakettiin, jota kutsutaan react-native -swiper käsittelemään näitä kolmea välilehteä sen sijaan. Ja olisin tosiasiallisesti ollut siinä hyvin, ellei välilehden alleviivojen melko äänettömiä dia-animaatioita olisi ollut. Joka tapauksessa pidasin kohtuullista hintaa välttää vaihtoehtoisia navigointipäänsärkyjä.

react-navigation TabNavigator vs react-native-swiper (huomioi kultaisen alaviivan eri animaatiot pyyhkäisemällä)

Yhteenvetona kokemuksestani navigoinnista React Nativessa:

  • Siellä on paljon hyvin dokumentoituja ratkaisuja, joista löysin reagointi-navigoinnin vastaamaan parhaiten tarpeitasi.
  • React-navigoinnin ansiosta aloittaminen on todella helppoa tietämättä paljon siitä, kuinka puhtaasti natiivi-navigointi toimii.
  • React-navigoinnilla on muutama ei-intuitiivinen ulottuvuus (web-kehittäjälle), mutta yhtään sellaista, jota ei voida valloittaa joillakin kämmenmielisillä työympäristöillä.

Aloitusruutu

Kun käynnistät uuden react-nattive init -sovelluksen simulaattorissasi ja lataat sovelluksen uudestaan ​​ja uudestaan ​​joka kerta, kun teet muutoksen, huomaat nopeasti tarpeeksi kauniita aloitusnäyttöä (kutsutaan myös splash screeniksi).

Ja koska tämän saavuttamiseksi on jo todella mahtava opas, en tuhlaa aikamme toistamalla kirjoittajan sanoja. Törmäsin vain yhteen ongelmaan, jota oppaassa ei käsitelty:

Se on melko paljon iOS-reunalaukku, mutta silti jotain, joka todennäköisesti häiritsee harvoja käyttäjiä, joille se altistuu. Löysin sen ensin työskennellessäni jossain, jossa en voinut käyttää wifi: tä, ja jakoin siten 4G puhelimesta kannettavan tietokoneen kanssa. Kuten iPhonen käyttäjät tietävät, laitteen tilarivi muuttuu siniseksi ja saa korkeamman korkeuden Internetin jakamisen aikana. Ja se rikkoi splash-näyttökuvani täysin, kun ajet laitteella. Sama ongelma ilmestyi puhelun aikana.

Joten hetken kuluttua kaivaamisesta reagoi alkuperäisen ruiskunäytön repo-ohjelmasta ja löytämättä mitään hyödyllistä, päätin kiertää ongelmaa piilottamalla tilarivin kokonaan, kun aloitusnäyttö oli näkyvissä.

Se on erittäin helppoa, sinun tarvitsee vain lisätä UIStatusBarHidden-avain tosi logiikka-arvoon info.plist-tiedostoosi ja asettaa sitten React Native StatusBar -komponentin ”piilotettu” potentiaali väärään, kun SplashScreen.hide () on kutsuttu .

Valtion hallinto

"Konferenssi kokoonpanon suhteen" on mantra, jonka minusta on kuullut joka toinen päivä kahden viime vuoden ajan. Ei vähiten entisen työnantajan luona. Ei kovin yllättävää, koska käytimme Ruby on Rails -palvelimen puolella ja Ember.js asiakaspuolella - kaksi kehystä, jotka ovat periaatteessa synonyymi kyseiselle sanonnalle. Luulin tietäväni mitä nämä sanat tarkoittivat, mutta prosessi oppia käsittelemään tilaa React Native -tapauksessa antoi heille aivan uuden merkityksen.

Vaikka olen pelannut verkon "kokoonpano yleissopimuksella" -reaktorikirjastossa muutamassa hyvin yksinkertaisessa demosovelluksessa, en ole koskaan rakennutut mitään tarpeeksi suurta perustelemaan valtionkontin, kuten Redux tai MobX, tuomista. Sen sijaan suurin osa JS: n valtionhallintakokemuksesta tuli Ember Datasta (Emberin sisäänrakennettu valtionhallinnan ja datan pysyvyyden kirjasto).

Koska Redux oli oikea ratkaisu, jonka olin kuullut ihmisten puhuvan vuosien ajan podcast-lähetyksissä, blogeissa ja videoissa (mukaan lukien Jordania RN Youtube -kurssilla), en koskaan oikein harkinnut mitään sen kilpailijoista. Halusin vain perustaa parhaan mahdollisen valtionhallinnon infrastruktuurin mahdollisimman pienellä vaivalla.

Emberissä sinulle annetaan periaatteessa 90% tästä infrastruktuurista ilmaiseksi. Tiesin, että minun piti hyväksyä päinvastainen suhde nykyisessä projektissani. Ei vain, että React tarjoaa sinulle jotain hyödyllistä globaalin tilan käsittelemiseen, mutta Redux - markkinoiden suosituin ratkaisu - on niin kevyt, että joudut lähtökohtaisesti vetämään 90% painosta itse, niin saat tasa-arvon. valtion ratkaisu.

Nyt kun hiukan nuorempi sain sen pois järjestelmästään, kova osa oli todella saada vain ripustettavaksi tämä uusi toimiva ja muuttumaton työnkulku. Kun olin hyväksynyt yllättävän suuren määrän uutta monimutkaisuutta, joka tarvitaan tietojen hakemiseen tai lähettämiseen vain palvelimelleni / palvelimelleni, se kaikki laski 7 melko yksinkertaiseen vaiheeseen:

  1. Lisää kolme SOME_ACTION_REQUEST, SOME_ACTION_FAILED, SOME_ACTION_SUCCEEDED vakiotiedostoosi.
  2. Lisää toiminnan luoja toimintotiedostoosi.
  3. Käsittele kolme toimintoa sopivalla pelkistimellä ja lisää tarvittaessa uusi pelkistin ja lisää se pelkistimeen juurreduktoriin.
  4. Lisää työntekijöitä sopivaan saagaan ja lisää tarvittaessa uusi saga ja lisää se saaga juurisagaasi (käytän redux-saagaa async-toimintoihin).
  5. Lisää toiminto käsittelemään mahdollisia API-pyyntöjä.
  6. Kartoita tarvittava tila rekvisiittamaan sopivia React-komponentteja.
  7. Lähetä SOME_ACTION_REQUEST-toimenpide sopivista React-komponenteista.

Reduxilla ja redux-saagalla on varmasti niin paljon enemmän tarjottavaa, mutta minusta tällä hetkellä olen sitä mieltä, että edellä mainitut 7 vaihetta ovat lähinnä mitä Redux on minulle.

istunnot

Joten meillä on React Native dev -ympäristömme perustettu, navigointipuu kartoitettu ja valtionhallinnon infrastruktuuri paikoillaan. Mikä olisi hyvä seuraava askel? No, minulle luonnollinen valinta oli käyttäjän todennus, jolloin pääsin istuntoihin.

Jos olet tulossa React Native -verkkoon web-taustalta, istuntojen käsitteleminen ei vaadi paljon aivojen laskentatehoa. Jos tunnet jollain tavalla LocalStorage-käsitteen, sinun on yksinkertaisesti korvattava se AsyncStorage: lla - abstraktiotasolla, joka antaa sinulle mahdollisuuden säilyttää avain-arvo-parit istuntojen välillä. Toisin sanoen täydellinen tallentamaan palvelimelta luotu todennustunnus käyttäjän kirjautuessaan sisään.

Listat

Kaiken kaikkiaan vaikutelmani on, että luettelot ovat melko hyvin ratkaistu ongelma React Nativessa. Periaatteessa sinulla on käsillä kolme vaihtoehtoa: Jos käsittelet staattista luetteloa, jonka tiedot eivät muutu, ScrollView riittää todennäköisesti. Jos kyseessä on suurempi ja dynaamisempi luettelo, FlatList on mitä haluat. Ja jos haluat suuremman ja dynaamisemman luettelon, joka on myös jaettu eri osioihin, SectionList on vastauksesi.

Olen käyttänyt yksinomaan FlatList-sovellusta dynaamisiin luetteloihini. Ja vaikka pidän intuitiivisesti siitä ja sen laajoista kokoonpanovaihtoehdoista, koin muutaman melko tuskallisen tilanteen. Alla aion käydä ne läpi yksi kerrallaan.

Vedä päivittääksesi
FlatListissä on päivitys nimeltä refreshControl, jolle voit välittää komponentin, jota haluat käyttää luettelon sisällön päivittämiseen, joka käynnistyy, kun käyttäjä vetää alaspäin luettelon yläosasta. Meille onnea, React Nativessa on komponentti juuri tätä tarkoitusta varten - RefreshControl. Kaikki erittäin intuitiivinen ja helppo asentaa.

RefreshControl toiminnassa

Olen kuitenkin joutunut outoon tilanteeseen, jossa refreshControl-prop ja / tai RefreshControl-komponentti näyttivät olevan syyllisiä. Jotain taustaa:

Joten luetteloissani haluan, että käyttäjät pystyvät a) vierittämään ylöspäin päivittämään luetteloa, käynnistämällä toiminimen, jonka nimeltin handleRefresh () ja b) vieritä alaspäin ladataksesi lisää kohteita luetteloon, aka. ”Ääretön vieritys” (enemmän siitä, alaspäin). Aika tavallista tavaraa.

Jonkin ajan kuluttua aloin kuitenkin saada tilanteita, joissa päivityskela vain jäätyisi ja jatkaisi pyörimistä ikuisesti, eikä näyttäisi palvelimelta haettuja uusia kohteita. Jonkin aikaa tutkittuaani löysin syy ongelmalleni tästä GitHub-kysymyksen vastauksesta.

Ongelmana oli, että sekä refreshControl että onEndReached (ääretön vieritys) rekvisiitta käyttivät samaa boolean-potkuria: “hakeminen”. Ja jostain outosta syystä, kun tämä nouto-propsiitti muuttuu väärin totta ja sitten takaisin takaisin totta, alle 250 ms: n aikavälissä, RefreshControl rikkoutuu ja lastauskehruu jäätyy.

Joten kokeilla tätä teoriaa yritin lisätä setTimeout (), asettamalla vähimmäisaikavälin 350 ms: n noutamisen loogisen arvon muuttamisen välillä. Ja se korjasi ongelman. Mutta koska setTimeout -sovelluksen käyttö tuntui hiukan liian mielekkäältä minun makuuni suhteen, päädyin lopulta ratkaisuun käyttää yksinkertaisesti kahta erilaista rekvisiittia kahvaRefresh () - ja handleLoadMore () -toimintoihin: ”virkistävä” ja “lastaaMore”. Etkö ole varma kuinka yleinen tämä ongelma on, mutta toivottavasti kiertotapa voi säästää jonkun aikaa ja turhautumista.

Huomaa, että virallisessa dokumentaatiossa suositellaan onRefresh- ja päivitysvaihtoehtojen käyttöä refreshControl-prop-laitteen sijaan. Syy siihen, että menin refreshControliin, oli, että en nähnyt muuta tapaa mukauttaa kehruun tyyliä.

Ääretön vierittäminen
Kuten edellä mainittiin, halusin myös antaa käyttäjilleni tunteen, kuin luettelo olisi täysin saumaton. Tarkoittaa sitä, että sinun ei tarvitse painaa mitään alaosassa olevaa “Lataa lisää” -painiketta ladataksesi lisää kohteita, eikä tarvitse joutua estämään lastauskehruuta tai lastauspaikkamerkkejä, jotka kattavat myös jo ladatun luettelon kohteen, samalla kun haet lisää kohteita.

Äärimmäisyyttä vieritetään FlatListillä (huomaa, kuinka 2-kynnysarvo laukaisee onEndReached-tilassa, kun olemme 2 näytön korkeuden arvoista luettelon kohteita alhaalta)

Tätä tarkoitusta varten onEndReached-ohjelmassa oli käytännössä kaikki mitä tarvitsin. Minulla oli kuitenkin kaksi ongelmaa sen toteuttamisessa.

Ensimmäinen oli kääriminen pääni onEndReachedThreshold-potkurin ympärille, joka kertoo FlatListillesi milloin käynnistää toiminnon, joka on siirretty onEndReachedille. Jonkin kokeilun ja virheen jälkeen selitykseni olisi seuraava:

Jos luetteloosi on ladattu 100 kohdetta ja näyttö sopii 10 kohtaan kerrallaan, onEndReachedThreshold-arvo 1 tarkoittaa, että onEndReached-toiminto kutsutaan, kun vierität luettelon 90. kohdan ohi. Jos arvo on 2, funktiota kutsutaan jo, kun olet 2 näytön korkeudessa lopusta, ts. 80. kohdasta jne.

Toinen ongelma, johon törmäsin ääretön vieritys, oli FlatList-virhe, jonka voin vain olettaa olevan. Nimittäin, että joka kerta, kun vieritän, ylitän kynnyksen, onEndReached-potentiaalille siirrettyä handleLoadMore () -toimintoa kutsutaan toistuvasti, usein yli 10 kertaa peräkkäin.

Sattumalta jälleen kerran ratkaisu löydettiin hyödyntämällä loadingMore-prop-ominaisuutta, lisäämällä if-lause lauseeseen handleLoadMore (), varmistaen, että hakutoiminto lähetettiin vain, jos! LoadingMore. Luonnollisesti haluat myös tarkistaa saman, jos lausunto siitä, että et ole palvelimen sivun viimeisellä sivulla.

Ladataan paikkamerkkejä
Jotain, jolla ei välttämättä olisi vaikutusta käyttökokemukseen, mutta joka ehdottomasti olisi tehnyt minut onnelliseksi kehittäjänä, olisi ListLoadingComponent-prop-palvelun esiintyminen FlatListissa, samoin kuin siellä on ListHeaderComponent, ListEmptyComponent ja ListFooterComponent.

Koska sitä ei ole, minun pakotettiin luottamaan kömpelöihin lauseisiin käsitelläksesi paikanvaraajan renderointia runsaasti render () -toimintoja.

Vieritä ylös
Viimeinen luetteloaihe, jota haluaisin koskea, vierittää luettelon yläosaan napin painalluksella. Sovelluksessani minulla on tällä hetkellä nämä painikkeet otsikoissa, mutta toinen yleinen sijainti heille on alareunan painikkeet.

Tämän saavuttamiseksi käytin FlatList scrollToOffset-menetelmää, joka on riittävän yksinkertainen ymmärtääksesi asiakirjoista. Tärkeä yksityiskohta, jota en löytänyt asiakirjoista, oli kuitenkin se, että joudut myös käyttämään RefL-tukea FlatList-komponentissa, kuten näin:

 {this.newsListRef = ref; }}
  ...
/>

Tämä tarkoittaa pohjimmiltaan sitä, että FlatListille annetaan tunniste, jotta sitä voidaan kutsua muualla olevasta toiminnosta. Joten minun tapauksessani se antoi minulle mahdollisuuden kutsua ScrollToOffset-toimintoa käsittelemästäsi toolScrollToTop () -toiminnosta ja välittää sen esimerkiksi parametrina react-navigation navigointiobjektille, jolloin se voidaan kutsua mistä tahansa reitistä, jolle param kulkee.

komponentDidMount () {
  this.props.navigation.setParams ({
    scrollToTop: this.handleScrollToTop,
  });
}
handleScrollToTop = () => {
  this.newsListRef.ScrollToOffset ({
    x: 0, y: 0, animoitu: totta,
  });
};

Huomaa, että päivittämisen jälkeen reakt-navigointiin 3 ei enää tarvinnut korjaamista, koska createBottomTabNavigator-painikkeet käsittelevät nyt oletuksena vierittämistä ylöspäin.

kuvat

Tulin oppimaan kuvat, joista suurin riski on tulla yhdeksi asiaksi, joka saa mobiilisovelluksesi imemään. Luonnollisesti tehokas kuvankäsittely on tärkeä myös verkossa, mutta koska puhelimet toimivat 4G: llä (tai 3G: llä, jumala kieltäkää) paljon suuremmassa määrin, on oletettava, että keskimääräinen latausnopeus on alhaisempi, mikä puolestaan ​​saattaa tehdä sovelluksestasi vaikuttavan hitaalta .

Kuvat vievät todennäköisesti myös suuremman osan puhelimen näytöstä verrattuna tietokoneen näytölle, miksi myös niille tulisi antaa korkeampi prioriteetti kosmeettisesta näkökulmasta. Joten vaikka se ei ehkä ole kaikkein hauskin osa kaikkea, jonkin aikaa sijoittaminen siihen on todennäköisesti sen arvoista.

Sovellus osoittautui melko raskaaksi kuvasisällölle. Se koostuu 7 luettelosta, joissa on luettelokohteet, joissa on rekvisiitta, jotka eivät näy vain varsinaisissa luettelokohteissa, vaan myös kunkin kohteen omilla ”yksityiskohdilla” (näyttö, johon käyttäjä ohjataan, kun painetaan luettelokohtaa).

Lähetetään kuvia
Käyttäjätilin muokkausnäytössä sovellus sallii myös käyttäjien ladata avatar-kuvan. Tätä varten käytin react-native-image-picker -kirjastoa sekä Cloudinary- ja Carrierwave-sovelluksia Rails-taustaohjelmallani.

Aluksi laitin kaiken latauslogiikan asiakaspuolelle käyttämällä Cloudinary's Node API -sovellusta ja react-native-fetch-blob -moduulia. Mutta jonkin ajan kuluttua, koska halusin hieman joustavampaa lähetyslogiikkaani ja en halunnut laittaa liikaa monimutkaista logiikkaa React Native -puolelle, siirrin sen kaiken Rails-taustaohjelmaan.

Olen kuitenkin joutunut ongelmiin yrittäessään lähettää kuvia palvelimelleni react-native-fetch-blob -sovelluksella. Siksi repon ylimääräinen monimutkaisuus ja tuolloin erittäin epävarma ylläpitotila sai minut valitsemaan sen sijaan sisäänrakennetun JS FormData API: n. Huomaa kuitenkin, että enää ylläpidetty reagoi-natiivi-haku-blob-repo on sittemmin siirretty rn-fetch-blobiin, jossa sitä ylläpidetään aktiivisesti.

Kuvien näyttäminen
Totuus on, että vakio React Native Image -tunniste tyylin, lähteen ja resizeMode-rekvisiittien avulla vie sinut pitkälle. Jos et välitä välimuistista, useiden kuvien näyttämisestä tai muusta kuvitteellisesta erikoistapauksesta, sinun ei todennäköisesti tarvitse tuoda muita riippuvuuksia.

Löysin kuitenkin kaksi tapausta, joissa tosiasiallisesti piti vaivan arvoista lisätä lisäystä riippuvuussuhteiden luettelooni. Ensimmäinen oli pyöreä avatar-muotoinen kuva, joka näkyi joissakin luettelokorteissa ja käyttäjäprofiileissa. Siksi reaktinatiiviset elementit Avatar olivat hyödyllisiä.

Haarautunut reagoi-natiivi -esitys toiminnassa

Tämä komponentti ei kuitenkaan tee mitään, jota et voi saavuttaa itselläsi jollain ylimääräisellä tyylillä oletuskuvakomponenttiin. Joten ellet ole jo tuonut kirjastoa muihin tarkoituksiin, en suosittele tämän riippuvuuden lisäämistä ainoaan tarkoitukseen kuin avatar-muotoilu.

Toinen tapaus, jossa päätin ulkoistaa, oli näyttää useita kuvia diaesityksessä (katso gif). Tätä varten käytin react-native-diaesityskirjastoa, joka teki tarkalleen mitä halusin.

Mutta varokaa, koska se on huonosti ylläpidetty, suosittelen voimakkaasti haarrua sitä ja leikkaamalla koodia vähän sen sijaan, että käytät kuten node_modules -sivustolta.

Ladataan paikkamerkkejä
Joten seitsemällä äärettömällä vieritysluettelolla, joissa on kuvia, käyttäjän on pakko odottaa jonkin verran, kun kaikki nämä tiedot noudetaan palvelimelta. Kuten kaikki tiedämme, odottaminen on luultavasti turhauttavin kokemus modernista tekniikasta. Joten luonnollisesti haluamme tehdä siitä mahdollisimman kestävän.

Kirjoita paikkamerkkejä.

En ole oikein varma miksi, mutta aina kun odotan jonkin sisällön latautumista, olen miljardia kertaa turhautunut, jos saan vain lastauskehruun (tai vielä pahempaa - ei ollenkaan), kuin jos näen kiiltävän , dynaamiset paikkamerkit Facebook-uutissyötteen tyyliin. Joten juuri sitä minä etsin.

Onneksi en ollut ensimmäinen, joka sai tämän idean React Native -tapahtumassa. Se ei vienyt paljon tutkimusta, ennen kuin pystyin varmasti asettumaan kahteen kirjastoon: reagoimaan-natiivi-lastaus-paikanvaraaja (todellisille paikkamerkeille) ja reagoimaan-natiivi-lineaarinen-gradientti (kiiltäville animaatioille). Olin todella tyytyväinen tulokseen, vaikka olisin saattanut viedä sen hieman liian pitkälle oikealla olevan kanssa…

Paikkamerkkien lastaus reagoi-natiivi-lastaus-paikkamerkillä ja reagoi-natiivi-lineaarinen-gradientilla

välimuistia
Kyllä, välimuisti on asia myös kotimaassa. Kummallista kyllä, RN Image -etätunnisteessa ei vielä ole sisäistä tukea sille. Sen sijaan käytät CachedImage-tunnistetta tästä suuresta kirjasta: reagoi-natiivi-välimuisti-kuva.

Periaatteessa kaikki mitä sinun tarvitsee tehdä, on asentaa npm-paketti ja vaihtaa kaikki välimuistiin tallennettavat oletuskuvatagit CachedImage: n avulla. Tämän jälkeen voit tarkistaa Reactotron-aikajanallasi varmistaaksesi, että kuvia todella tallennetaan.

Verrattuna minimaaliseen ponnisteluun, joka tarvitaan kuvan välimuistin asentamiseen, voitto on valtava. Oli todella tyytyväistä nähdä, kuinka pilvipalvelun kaistanleveyteni putosivat mojovaisesta 95 prosentista ilmaisesta kuukausikiintiöstä noin 4 prosenttiin.

Pro-vinkki: lisää prop activityIndicatorProps = {{animating: false}} ja vieritä omaa latauspaikkatietoa tavallisen latauskelan sijaan kuvan lataamisen aikana.

Aika

Aikavalitsin
React Nativella on tosiasiassa monen alustan Picker-komponentti. Koska se on hyvin muokattavissa oleva luonne (ja kärsimättömyyteni), etsin kuitenkin ympärilleni JS-kirjastoa, joka oli jo tehnyt osan työstä minulle. Onneksi löysin react-native-picker-select, joka jäljittelee alkuperäisiä