Tänään avataan pienellä esimerkillä ReactJS:ää eteenpäin. Tehdään komponentti, joka on Reactin peruspalikka. Kirjoitussarja seuraa lähes livenä omaa React -kehitykseni kulkua. Tämä on toinen osa. Ympäristö on asennettu osassa 1.
Se ‘opinionated’ eli ideologinen puoli
React sisältää, kuten Angular ja monet muut frameworkit, kohtuullisen paljon valmiita käytäntöjä. Siksi pelkästään päällipuolinen sorsakoodin katsastelu saattaa jättää monia kysymyksiä avoimeksi. Kannattaa aina välillä lukaista jokin kokonaisuus, vaikka React:n virallisilta dokumentaatiosivuilta. Alkuvaiheissa hyvä on esimerkiksi React Component (kaikki omat komponentit perivät tästä).
Kun opiskelen itse Reactia käytännössä “nollasta” eteenpäin, seuraavat asiat tökkivät alkuun:
- herkkä (ja perus vanilla-Javascriptiin verrattuna uusi) syntaksi; jos syntaksi on väärin, pieni virhe aiheuttaa yleensä tyhjän sivun selaimessa, ei kovin paljoa vihjeitä mistä etsiä bugia… mutta:
- Sublime Text 3 editori ja sopivat lisäosat auttoivat alkuun, koska monesti hapuillessa oikeaa syntaksia sai askel askeleelta vihjeitä miten päästä oikeaan lopputulokseen
- ihan ensialkuun tekstieditorin asetusten löytäminen sopivaksi, jotta ESLint -syntaksitarkistaja antaa React-ohjelman kääntyä puhtaasti
ESLint on osa esimerkkimme build-sykliä. Koska JSX menee Babel-kääntäjälle, on ilmeisesti normaalia tärkeämpää että syntaksi on juuri kohdallaan, eikä melkein sinne päin. JavaScript:hän jättää jonkun verran vapauksia valita syntaksiin liittyviä asioita, mutta JSX ja React ovat sen sijaan varsin tiukkoja. Huomasin alussa nyplääväni editorissa hyvin lyhyttä ohjelmaa ainakin vartin; hain melkeinpä kokeilemalla oikeaa muotoa.
Alkuun asia voi hidastaa kokeilua ja koodaamista, mutta kun tyyliin on päässyt sisälle, homma ei enää nouse ongelmaksi.
Jos editorissa tuntuu olevan syntaksiväritys (syntax highlighting) päin mäntyä, kokeile antaa Babel/JavaScript olla tulkkina sen sijaan että yrität lähdekoodille normaalia JavaScript-asetusta. Erona on siis se, että Babel:in avulla voidaan laajentaa erilaisia kielimurteita, jotka antavat värittimelle oikean rakenteen ja siten värit kohdalleen. Suoraan “Javascriptinä” tulkittuna tuo JSX olisikin virheellistä.
React: komponentit
Koodaaminen perustuu pariin keskeiseen asiaan: komponenttien määrittelyyn ja parametrien välittämiseen komponenteille. Kaikki komponentit perivät perusluokasta React.Component
Paljonko React nojaa ES6 -muotoon JavaScriptistä?
ES6 :sta ei ole pakko tietää kaikkea, riittää alkuun kun katsot miten ‘class’ toimii: se on luokkamäärittely, joka lopulta kääntyy “yksinkertaisemmaksi” JavaScriptiksi. Babel on tuo kääntäjä, joka hoitelee magian ES6 -tyyppisen lähdekoodin ja lopullisen käännöstuotteen välillä.
Class -määrittely (ES6)
Kannattaa katsoa Class -määrittely (ES6)
Perusidea on siis yksinkertaisempi ja lyhyempi syntaksi. Lopulta käännetty JavaScript on aivan samaa koodia, mutta nyt lähdekoodi pysyy puhtaamman näköisenä.
- yksinkertaista määritellä luokka
- luokan sisällä olevat funktiot kirjoitetaan “helpommin”, ei tarvitse määritellä turhaa formalismia:
funkkari (parametrit) { tänne koodi } - Perusmuoto ‘class’ avulla tehdystä luokasta:
Class OmaKomponentti extends React.Component - luokka sulkee sisälleen yksityiskohdat, jolloin globaali nimiavaruus pysyy mahdollisimman siistinä.
Tilatonta rakkautta, toistaiseksi
Myöhemmin sarjassa palataan koko sovelluksen tilan hallintaan; Reactissa komponentit eivät voi suoraan muokata tilaa (muuttujia, objekteja), koska on haluttu pitää tiedon liikkuminen yksisuuntaisena. Eli komponentille päin voidaan välittää tietoa kutsujalta, mutta ei takaisin. Ns. two-way binding, joka on mm. AngularJS:ssä keskeinen ominaisuus, on myös sellainen, joka usein saattaa karata käsistä: sekä suorituskyky koodissa laskee, että bugien jahtaaminen monimutkaistuu. React haluaa, että komponentit tekevät selkeästi rajatun asian eli pitävät huolen ruudulla näkyvien (UI) asioiden muuttamisesta; that’s it – ei muuta.
Kädet saveen: komponentti
Lähdetään penkomaan, miten asennettu esimerkki oikein toimii. Jos et ole vielä asentanut runkoa koneellesi, käy vilkaisemassa aiempi osa blogauksesta: React alkuun, kaverina Yeoman
index.js käynnistää sovelluksen elinkaaren. Siellä on oikeastaan vain kutsu näyttää yksi itse määritelty komponentti:
Keskeisin osa lähdekoodista löytyy 2 tiedostosta:
src/index.js
src/components/Main.js
Alempi, “Main.js” määrittelee komponentin – eli päätason komponentin. App kutsuu muita komponentteja, eli se sisältää perus layoutin, komponenttitasolla.
Rivi riviltä tärkeimmät osat komponentista (Main.js)
Komponentin perusasiat ovat:
- ympäristön asetus sopivaksi
- luokan määrittely
- render() funktio on komponentin tärkein pihvi
- export – eli kerrotaan mikä osa komponentista avataan kutsujalle (koodin käyttäjälle)
Komponetti piilottaa siis kutsujaltaan turhat yksityiskohdat. Tässä on eräs Reactin kulmakivi: monessa muussa frameworkissa ohjelmoija voi pian olla scope-sotkun kanssa tekemisissä.
Scope menee ylikansoitetuksi helposti, jos ohjelma on pitkä, ja sitä ei jaa moduleihin.
Reactissa on tavallaan nihilistinen, yksinkertainen malli, jossa yritetään noudattaa klassisen olio-ohjelmoinnin kapsulointia – ideaa siitä, että jokainen olio (komponentti) pitäköön yksityiskohtansa omana tietonaan. Komponentin kutsuja on vain kiinnostunut rajapinnasta komponenttiin: mitä se ottaa vastaan, ja mitä se lupaa tehdä.
Komponentin vastuulle jää koodi, joka luo normaaliin tapaan HTML:llä ja CSS:llä ja JavaScript-koodilla toiminnallisuutta.
Komponentti voi myös tarvita omaa tilaa (‘state’) eli muistia. Esimerkkinä Reactin englanninkielisillä dokumenttisivuilla on tehty kello, joka pitää kirjaa ajasta. Tieto ajasta kapsuloidaan kello-komponentin sisälle, koska se ei oikeasti kiinnosta ympäröivää sovellusta.
Reactissa sen sijaan muokataan tilaa viittaamalla eksplisiittisesti tilan säilövään yhteen globaaliin funktioon.
Tärkeät muistisäännöt
Katsotaan mitä koodista löytyy
- komponentitkin joutuvat itsenäisesti käyttämään require() :eja pakettien sisällyttämiseen
- komponentin koodissa alussa myös tärkeä import
- render() funktio pitää aina olla komponentilla
- pidä render() mahdollisimman lyhyenä ja siistinä, monimutkaisempaa käsittelykoodia voi laittaa komponentti-luokkaan render() :n rinnalle
- render() :ssä muista palauttaa aina ensin yksi div -elementti
jonka sisälle on kääritty muu haluamasi sisältö
Toisin sanoen Reactissa komponentti on niin itsenäinen palikka, että se ei automaattisesti saa ympäristöstä muiden osien käyttämiä require ja import -määrityksiä. Jokainen komponentti huolehtii itse sopivien määritysten tekemisestä. Jos tarvitset komponentissa jotain resurssia, muista kirjoittaa tarvittavat sisällytykset.
Leave a Reply