Tila: Komponentin muisti
Components often need to change what’s on the screen as a result of an interaction. Typing into the form should update the input field, clicking “next” on an image carousel should change which image is displayed, clicking “buy” should put a product in the shopping cart. Components need to “remember” things: the current input value, the current image, the shopping cart. In React, this kind of component-specific memory is called state.
Tulet oppimaan
- Miten lisätä tilamuuttuja
useState
hookilla - Minkä arvoparin
useState
hookki palauttaa - Miten lisätä useampi tilamuuttuja
- Miksi tilaa sanotaan paikalliseksi
Kun tavallinen muuttuja ei riitä
Tässä on komponentti, joka renderöi kuvan veistoksesta. Klikkaamalla “Next” painiketta pitäisi seuraavan veistoksen näkyä, muuttamalla index
lukua 1
:een, 2
:een ja niin edelleen. Kuitenkaan tämä ei toimi (voit kokeilla!):
handleClick()
tapahtumakäsittelijä päivittää paikallista index
muuttujaa. Kaksi asiaa kuitenkin estävät muutoksen näkymisen:
- Paikalliset muuttujat eivät pysy voimassa renderien välillä. Kun React renderöi tämän komponentin toiseen kertaan, se luo sen alusta. Se ei ota huomioon paikallisten muuttujien muutoksia.
- Muutokset paikallisiin muuttujiin eivät käynnistä uutta renderöintiä. React ei huomaa, että sen täytyy renderöidä komponentti uudelleen uusien tietojen kanssa.
Päivittääksesi komponentti uudella datalla, kaksi asiaa täytyy tapahtua:
- Säilyttää data renderien välillä.
- Käynnistää React renderöimään komponenttin uudella datalla (uudelleenrenderöinti).
useState
hookki tarjoaa molemmat näistä:
- Tilamuuttujan ylläpitämään data renderien välillä.
- Tilan asettajafunktio päivittämään muuttujaa ja käynnistämään komponentin uudelleenrenderöinti.
Tilamuuttujan lisääminen
Lisätäksesi tilamuuttuja, importtaa useState
Reactista tiedoston alussa:
import { useState } from 'react';
Sitten, korvaa tämä rivi:
let index = 0;
tällä
const [index, setIndex] = useState(0);
index
on tilamuuttuja ja setIndex
on tilan asettajafunktio.
Aaltosulkeilla
[
ja]
oleva syntaksi on nimeltään array destructuring ja sen avulla voit lukea arvoja listasta.useState
palauttaa aina listan, jossa on kaksi kohdetta.
Tässä miten ne toimii yhdessä handleClick()
funktiossa:
function handleClick() { setIndex(index + 1); }
Nyt klikkaamalla “Next” painiketta, kuva veistoksesta vaihtuu:
Tapaa ensimmäinen hookkisi
Reactissa useState
, kuten muutkin funktiot jotka alkavat sanalla ”use
”, ovat hookkeja.
Hookit ovat erityisiä funktioita, jotka ovat saatavilla vain kun React renderöi (aihe, johon perehdymme enemmän seuraavalla sivulla page). Näillä voit “koukata” erilaisiin Reactin toimintoihin.
Tila on vain yksi näistä toiminnoista, mutta tulet tapaamaan toiset hookit myöhemmin.
useState
:n anatomia
Kun kutsut useState
:a, sanot Reactille, että haluat tämän komponentin muistavan jotain:
const [index, setIndex] = useState(0);
Tässä tapauksessa haluat Reactin muistavan index
:n.
Ainoa argumentti useState
:lle on tilamuuttujan aloitusarvo. Tässä esimerkissä index
:n aloitusarvo on 0
kun käytimme useState(0)
.
Joka kerta kun komponenttisi renderöityy, useState
palauttaa listan sisältäen kaksi kohdetta:
- Tilamuuttujan (
index
) missä on arvo, jonka tallensit. - Tilan asettajafunktion (
setIndex
) joka voi piäivittää tilamuuttujaa ja käynnistää komponentin uudelleenrenderöinnin.
Tässä miten se tapahtuu toiminnassa:
const [index, setIndex] = useState(0);
- Your component renders the first time. Koska välitit arvon
0
,useState
-arvonindex
alkuarvoksi, se palauttaa arvon[0, setIndex]
. React muistaa, että0
on viimeisin tila-arvo. - Päivität tilan. Kun käyttäjä klikkaa painiketta, se kutsuu
setIndex(index + 1)
.index
on0
, joten se onsetIndex(1)
. Tämä käskee Reactia muistamaan, ettäindex
on nyt1
ja käynnistämään toisen renderöinnin. - Komponenttisi toinen renderöinti. React näkee silti
useState(0)
, mutta koska React muistaa, että asetitindex
:n aroon1
, se palauttaa[1, setIndex]
kuitenkin. - Ja niin edelleen!
Useiden tilamuuttujien antaminen komponentille
Voit lisätä niin monta tilamuuttujaa niin monessa eri tyypissä kuin haluat komponentin sisälle. Tällä komponentilla on kaksi tilamuuttujaa, index
numero sekä showMore
totuusarvo, jota vaihdetaan kun klikkaat “Show details”:
Hyvä idea on tehdä useita tilamuuttujia jos ne eivät liity toisiinsa, kuten index
ja showMore
tässä esimerkissä. Mutta jos löydät itsesi usein vaihtamassa kahta tilamuuttujaa yhdessä, saattaa olla helpompaa yhdistää ne yhteen. Esimerkiksi, jos sinulla on lomake monilla kentillä, voi olla kätevää pitää tila yhdessä oliossa ennemin kuin yksi tilamuuttuja per kenttä. Tilarakenteen päättäminen -sivulla on enemmän vinkkejä tähän.
Syväsukellus
Olet saattanut huomata, että useState
kutsu ei vastaanota tietoa siitä mitä tilamuuttujaa se vastaa. Ei ole mitään “tunnistetta”, joka välitettäisiin useState
:lle, joten miten se tietää minkä tilamuuttujan palauttaa? Nojaako se johonkin taikaan kuten funktioiden parsimiseen? Ei.
Sen sijaan, mahdollistaakseen niiden tiiviin syntaksin, hookit turvautuvat vakaaseen kutsujärjestykseen saman komponentin jokaisella renderöinnillä. Tämä toimii hyvin käytännössä, koska jos seuraat ylhäällä mainittua sääntöä (“kutsu hookkeja vain ylätasossa”), hookit tullaan kutsumaan aina samassa järjestyksessä. Lisäksi, lintteri-lisäosa huomaa suurimman osan virheistä.
Sisäisesti, React pitää yllään listan tilamuuttujapareista jokaiselle komponentille. Se pitää yllään myös sen hetkistä indeksiä, joka on asetettu 0
:ksi ennen renderöintiä. Joka kerta kun kutsut useState
:a, React antaa sinulle seuraavan tilaparin ja kasvattaa indeksiä. Voit lukea lisää tästä mekanismista linkistä: React Hooks: Not Magic, Just Arrays.
Tämä esimerkki ei käytä Reactia, mutta antaa idean siitä miten useState
toimii sisäisesti:
Sinun ei tarvitse ymmärtää tätä käyttääksesi Reactia, mutta saatat kokea sen hyödyllisenä.
Tila on eristetty ja yksityinen
Tila on paikallinen kussakin komponentissa. Toisin sanoen, jos renderöit saman komponentin kahdesti, kummallakin on niiden oma eristetty tila! Yhden muuttaminen ei vaikuta toiseen.
Tässä esimerkissä, aiempi Gallery
komponetti renderöidään kahdesti ilman muutoksia sen logiikkaan. Kokeile klikata painikkeita kummassakin galleriassa. Huomaat, että niiden tilat ovat itsenäisiä:
Tämä tekee tilasta erilaisen kuin tavalliset muuttujat, joita saatat määritellä moduulisi yläosassa. Tilaa ei ole yhdistetty tiettyyn funktiokutsuun tai paikkaan koodissa, mutta se on “paikallinen” siinä kohtaa ruutua. Renderöit kaksi <Gallery />
komponenttia, joten niiden tila on tallennettu erillään.
Huomaa myös kuinka Page
komponentti ei “tiedä” mitään Gallery
:n tilasta tai edes onko sillä tilaa. Toisin kuin propsit, tila on täysin yksityinen komponentille, joka sen määrittelee. Yläkomponetti ei voi muuttaa sitä. Tämän avulla voit lisätä tilan mihin tahansa komponenttiin tai poistaa sen vaikuttamatta muihin komponentteihin.
Entä jos haluaisit molempien gallerioiden pitäbän niiden tilan synkronisoituna? Oikea tapa tehdä tämä Reactissa on poistamalla tila alakomponenteista ja listätä se niiden lähimpään jaettuun yläkomponenttiin. Seuraavat muutamat sivut keskittyvät yhden komponentin tilan järjestämiseen , mutta palaamme tähän aiheeseen Sharing State Between Components -sivulla.
Kertaus
- Käytä tilamuuttujaa kun komponentin täytyy “muistaa” jotain tietoa renderien välillä.
- Tilamuuttujat määritellään kutsumalla
useState
hookkia. - Hookit ovat erityisiä funktioita, jotka alkavat sanalla
use
. Niiden avulla voit “koukata” Reactin toimintoihin kuten tilaan. - Hookit saattavat muistuttaa sinua importeista: ne pitää kutsua ilman ehtoja. Hookkien kutsuminen,
useState
mukaanlukien, on sallittua vain komponentin yläosassa tai toisessa hookissa. useState
hookki palauttaa arvoparin: nykyisen tilan ja funktion jolla päivittää sitä.- Voit tehdä useita tilamuuttujia. Sisäisesti, React yhdistää ne järjestyksen perusteella.
- Tila on yksityistä komponentille. Jos renderöit niitä kahdessa paikassa, kukin saa oman tilan.
Haaste 1 / 4: Viimeistele galleria
Kun painat “Next” painiketta viimesellä veistoksella, koodi kaatuu. Korjaa logiikka joka estää kaatumista. Voit tehdä tämän lisäämällä logiikkaa tapahtumakäsittelijään tai poistamalla painikkeen käytöstä kun toimintoa ei ole mahdollista tehdä.
Korjaamisen jälkeen, lisää “Previous” painike, joka näyttää edellisen veistoksen. Sen ei tulisi kaatua ensimmäisessä veistoksessa.