Pika-aloitus
Tervetuloa Reactin dokumentaatioon. Tällä sivulla esitellään 80% Reactin konsepteista, joita käytät päivittäin.
Tulet oppimaan
- Miten luodaan ja sijoitetaan komponentteja
- Miten lisätään merkintäkoodia ja tyylejä
- Miten tietoja näytetään
- Miten renderöidään listoja ja ehtoja
- Miten vastataan tapahtumiin ja päivitetään ruutua
- Miten tietoa jaetaan komponenttien välillä
Komponenttien luominen ja sijoittaminen
React sovellukset koostuvat komponenteista. Komponentti on pala käyttöliittymää (UI, user interface), jolla on sen oma logiikka ja ulkomuoto. Komponentti voi olla pieni kuin painonappi tai suuri kuin koko sivu.
React komponentit ovat JavaScript funktioita, jotka palauttavat merkintäkoodin:
function Painonappi() {
return (
<button>Olen painike</button>
);
}
Nyt kun on esitelty Painonappi
-komponentti, voidaan se sijoittaa toisen komponentin sisään:
export default function MyApp() {
return (
<div>
<h1>Tervetuloa sovellukseeni</h1>
<Painonappi />
</div>
);
}
Huomaa, että <Painonappi />
alkaa isolla alkukirjaimella. Tästä voit päätellä, että kyseessä on React komponentti. React komponentin nimen on aina alettava isolla alkukirjaimella, kun taas HTML tagit alkavat pienellä alkukirjaimella.
Katsotaanpa lopputulosta:
function Painonappi() { return ( <button> Olen painke </button> ); } export default function MyApp() { return ( <div> <h1>Tervetuloa sovellukseeni</h1> <Painonappi /> </div> ); }
Avainsanat export default
määrittävät tiedoston pääkomponentin. Mikäli JavaScript syntaksi ei ole tuttua, MDN ja javascript.info ovat hyviä tietolähteitä.
Merkintäkoodin kirjoittaminen JSX:llä
Merkintäkoodi jota näit ylhäällä kutsutaan nimeltään JSX. Sen käyttö on valinnaista, mutta useimmat React projektit käyttävät JSX:ää sen mukavuuden vuoksi. Kaikki työkalut, joita suosittelemme paikalliseen kehitykseen tukevat JSX:ää oletuksena.
JSX on tarkempaa kuin HTML. Sinun täytyy sulkea tagit kuten <br />
. Komponenttisi ei myöskään voi palauttaa useampia JSX tageja, vaan ne täytyy kääriä yhden pääelementin sisään, kuten <div>...</div>
tagiin tai tyhjään <>...</>
elementtiin:
function TietoaSivu() {
return (
<>
<h1>Tietoa</h1>
<p>
Heippa.<br />Mitä kuuluu?
</p>
</>
);
}
Mikäli sinulla on paljon HTML merkintäkoodia muutettavana JSX koodiksi, voit käyttää verkkomuunninta.
Tyylien lisääminen
Reactissa määrittelet CSS luokat käyttämällä className
attribuuttia. Se toimii samoin kuin HTML kielen class
attribuutti:
<img className="avatar" />
Tämän jälkeen kerrot tyylimäärittelyt erilisessä CSS tiedostossa:
/* CSS koodissasi */
.avatar {
border-radius: 50%;
}
React ei määrää miten lisäät CSS tiedostot. Yksinkertaisimmillaan lisäät <link>
tagin HTML merkintäkoodiin. Jos käytät käännöstyökalua tai ohjelmistokehystä, konsultoi niiden dokumentaatiota löytääksesi tavan lisätä CSS tiedostoja projektiisi.
Tiedon näyttäminen
JSX mahdollistaa merkintäkoodin käytön JavaScriptissa. Aaltosulkeilla voit “peruuttaa takaisin” JavaScriptiin, jotta voit upottaa jonkun muuttujan koodistasi ja näytää sen käyttäjälle. Esimerkiksi, tämä tulostaa kayttaja.nimi
:
return <h1>{kayttaja.nimi}</h1>;
Voit myös “peruuttaa takaisin JavaScriptiin” JSX attribuutissa, mutta tässä täytyy käyttää aaltosulkeita lainausmerkkien sijaan. Esimerkiksi className="avatar"
syöttää "avatar"
merkkijonon CSS luokaksi, mutta src={kayttaja.kuvanUrl}
lukee JavaScriptissa kayttaja.kuvanUrl
muuttujan arvon ja palauttaa sen src
attribuuttiin:
return <img className="avatar" src={kayttaja.kuvanUrl} />;
JSX aaltosulkeisiin voi laittaa myös laajempia lausekkeita, esimerkiksi merkkijonojen yhdistämistä:
const kayttaja = { nimi: 'Hedy Lamarr', kuvanUrl: 'https://i.imgur.com/yXOvdOSs.jpg', kuvanKoko: 90, }; export default function Profiili() { return ( <> <h1>{kayttaja.nimi}</h1> <img className="avatar" src={kayttaja.kuvanUrl} alt={'Kuva henkilöstä ' + kayttaja.nimi} style={{ width: kayttaja.kuvanKoko, height: kayttaja.kuvanKoko, }} /> </> ); }
Ylläolevassa esimerkissä käytetty style={{}}
ei ole erityistä syntaksia, vaan normaali {}
olio JSX aaltosulkeiden style={ }
sisällä. Voit käyttää style
attribuuttia kun tyylisi riippuu JavaScript muuttujista.
Ehdollinen renderöinti
Reactissa ei ole erityistä syntaksia ehtolauseiden kirjoittamiseen. Sen sijaan voit käyttää samoja tekniikoita kuin mitä käytät kirjoittaessasi tavallista JavaScript koodia. Esimerkiksi, voit käyttää if
lausetta sisällyttämään JSX koodia ehdollisesti:
let sisalto;
if (onkoKirjautunutSisaan) {
sisalto = <Hallintapaneeli />;
} else {
sisalto = <Kirjautumislomake />;
}
return <div>{sisalto}</div>;
Mikäli suosit kompaktimpaa koodia, voit käyttää ?
operaattoria. Toisin kuin if
, se toimii myös JSX:n sisällä:
<div>{onkoKirjautunutSisaan ? <Hallintapaneeli /> : <Kirjautumislomake />}</div>
Kun et tarvitse else
osaa, voit käyttää lyhyempäää loogista &&
syntaksia:
<div>{onkoKirjautunutSisaan && <Hallintapaneeli />}</div>
Kaikki nämä tavat toimivat myös attribuuttien ehdolliseen määrittelyyn. Jos jokin tässä käyty JavaScript syntaksi ei ole tuttua, voit aina aloittaa käyttämällä if...else
.
Listojen renderöinti
Tulet käyttämään JavaScriptin ominaisuuksia kuten for
silmukkaa sekä array map()
funktiota komponenttilistojen renderöintiin.
Esimerkiksi, sanotaan, että sinulla on lista tuotteista:
const tuotteet = [
{otsikko: 'Kaali', id: 1},
{otsikko: 'Valkosipuli', id: 2},
{otsikko: 'Omena', id: 3},
];
Komponentin sisällä voit käyttää map()
funktiota muuttaaksesi tuotelistan listaksi <li>
elementtejä:
const listaKohteet = tuotteet.map((tuote) => (
<li key={tuote.id}>{tuote.otsikko}</li>
));
return <ul>{listaKohteet}</ul>;
Huomaa miten <li>
elementillä on key
attribuutti. Jokaiselle listan kohteelle tulisi antaa merkkijono tai numero, joka yksilöllisesti erottaa kohteen sen sisaruksista. Useimmiten, avain tulisi suoraan tietolähteestä, kuten tietokannan ID kentästä. React hyödyntää avaimiasi ymmärtääkseen mitä tapahtui jos myöhemmin lisäät, poistat tai uudelleenjärjestät kohteita.
const tuotteet = [ {otsikko: 'Kaali', onHedelma: false, id: 1}, {otsikko: 'Valkosipuli', onHedelma: false, id: 2}, {otsikko: 'Omena', onHedelma: true, id: 3}, ]; export default function Ostoslista() { const listaKohteet = tuotteet.map((tuote) => ( <li key={tuote.id} style={{ color: tuote.onHedelma ? 'magenta' : 'darkgreen', }}> {tuote.otsikko} </li> )); return <ul>{listaKohteet}</ul>; }
Vastaaminen tapahtumiin
Voit vastata tapahtumiin määrittelemällä Tapahtumankäsittelijän komponenttiesi sisällä:
function Painonappi() {
function kunKlikataan() {
alert('Napsautit minua!');
}
return (
<button onClick={kunKlikataan}>
Napsauta minua
</button>
);
}
Huomaa miten onClick={kunKlikataan}
ei sisällä sulkeita lopussa! Älä kutsu Tapahtumankäsittelijää: sinun täytyy ainoastaan välittää se. React kutsuu Tapahtumankäsittelijääsi kun käyttäjä napsauttaa painiketta.
Ruudun päivittäminen
Usein haluat, että komponenttisi “muistaa” jotain tietoa ja näyttää sitä. Esimerkiksi, ehkäpä haluat laskea montako kertaa painiketta on napsautettu. Tehdäksesi tämän, lisää tila eli state komponenttiisi.
Ensiksi, importtaa useState
Reactista:
import {useState} from 'react';
Nyt voit määritellä tilamuuttujan komponentin sisällä:
function Painonappi() {
const [count, setCount] = useState(0);
// ...
Saat kaksi asiaa useState
:lta. Tämänhetkisen tilan (count
), ja funktion jolla voit päivittää sitä (setCount
). Voit antaa niille mitkä tahansa nimet, mutta käytäntö on kutsua niitä seuraavasti: [something, setSomething]
.
Ensimmäisen kerran kun painike näytetään, count
on 0
koska useState()
määrittelyssä annettiin 0
. Kun haluat muuttaa tilaa, kutsu setCount()
funktiota ja anna sille uusi arvo. Painiketta napsauttamalla luku kasvaa:
function Painonappi() {
const [count, setCount] = useState(0);
function kunKlikataan() {
setCount(count + 1);
}
return <button onClick={kunKlikataan}>Napsautettu {count} kertaa</button>;
}
React kutsuu komponenttifunktiota uudelleen. Silloin count
on 1
. Sitten se tulee olemaan 2
. Ja niin edelleen.
Jos renderöit saman komponentin useita kertoja, kullakin komponentilla on oma tilansa. Kokeile napsauttaa painikkeita erikseen:
import {useState} from 'react'; export default function MyApp() { return ( <div> <h1>Laskurit, jotka päivittyvät erikseen</h1> <Painonappi /> <Painonappi /> </div> ); } function Painonappi() { const [count, setCount] = useState(0); function kunKlikataan() { setCount(count + 1); } return <button onClick={kunKlikataan}>Napsautit {count} kertaa</button>; }
Huomaa miten kukin painike “muistaa” sen oman count
tilan eikä se vaikuta muihin painikkeisiin.
Hookkien käyttäminen
Funktiot, jotka alkavat sanalla use
ovat hookkeja. useState
on Reactin sisäänrakennettu hookki. Löydät lisää sisäänrakennettuja hookkeja React API referenssistä. Voit myös kirjoittaa omia Hookkeja olemassaolevia yhdistelemällä.
Hookit ovat rajoittavampia kuin normaalit funktiot. Voit kutsua hookkeja ainoastaan komponentin päätasolta (tai muista hookeista). Jos haluat käyttää useState
hookkia ehdollisesti tai loopissa, luo uusi komponentti ja sijoita se sinne.
Tiedon jakaminen komponenttien välillä
Aikaisemmassa esimerkissä jokaisella Painonappi
komponentilla oli sen oma count
tila, ja kun yksittäistä painiketta napsautettiin, vain painetun painikkeen count
tila muuttui:
Usein kuitenkin komponenttien täytyy jakaa tietoa ja päivittyä sen mukana.
Jotta molemmat MyButton
komponentit näyttävät saman count
luvun sekä päivittyvät sen mukana, täytyy yksilöllinen tila poistaa nappi -komponenteilta “ylöspäin” lähimmälle pääkomponentille.
Tässä esimerkissä se on MyApp
:
Nyt kun klikkaat kumpaakin painiketta, count
tila MyApp
komponentissa muuttuu. Tämä muutos muuttaa molempien MyButton
komponenttien tilat.Tässä vielä miten se tehtäisiin koodissa.
Ensiksi, siirrä tila ylöspäin MyButton
komponentista MyApp
komponenttiin:
function MyButton() {
}
export default function MyApp() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>Laskurit, jotka päivittyvät erikseen</h1>
<MyButton />
<MyButton />
</div>
);
}
function MyButton() {
// ... siirretään tila täältä ...
}
Sitten anna tila alaspäin MyApp
komponentissa kuhunkin MyButton
komponenttiin yhdessä klikkauksen Tapahtumankäsittelijän kanssa. Voit antaa tietoa MyButton
komponenttiin käyttäen JSX aaltosulkeita, aivan kuten aiemmin teit sisäänrakennettujen <img>
tagien kanssa:
export default function MyApp() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>Laskurit jotka päivittyvät yhdessä</h1>
<MyButton count={count} onClick={handleClick} />
<MyButton count={count} onClick={handleClick} />
</div>
);
}
Tietoa, jota annat alaspäin näin kutsutaan propseiksi (engl. props). Nyt MyApp
komponentti sisältää count
tilan, handleClick
Tapahtumankäsittelijän, sekä antaa molemmat näistä propseina kullekin painikkeelle.
Lopuksi, mutta MyButton
lukemaan propsit, jotka annoit sille sen pääkomponentista:
function MyButton({count, onClick}) {
return (
<button onClick={onClick}>
Napsautit {count} kertaa
</button>
);
}
Kun klikkaat painiketta, onClick
Tapahtumankäsittelijää kutsutaan. Jokaisen painikkeen onClick
propsi on asetettu handleClick
funktioon MyApp
komponentissa, joten koodi sen sisällä suoritetaan. Se koodi kutsuu setCount(count + 1)
, nostaen count
tilamuuttujaa. Uusi count
tila välitetään propsina kullekin painikkeelle jolloin ne kaikki näyttävät samaa uutta arvoa. Tätä kutsutaan “tilan nostamiseksi ylös”. Siirtämällä tilaa ylös jaamme sitä komponenttien välillä.
import {useState} from 'react'; export default function MyApp() { const [count, setCount] = useState(0); function handleClick() { setCount(count + 1); } return ( <div> <h1>Laskurit jotka päivittyvät yhdessä</h1> <MyButton count={count} onClick={handleClick} /> <MyButton count={count} onClick={handleClick} /> </div> ); } function MyButton({ count, onClick }) { return ( <button onClick={onClick}> Napsautit {count} kertaa </button> ); }
Seuraavat vaiheet
Nyt tiedät perusteet siitä miten kirjoitetaan React koodia!
Katso seuraavaksi Oppaat laittaaksesi ne käytäntöön ja rakentaaksesi ensimmäisen mini-React sovelluksen.