Kuinka tulla ammattilaiseksi React setState (): n avulla 10 minuutissa
Tämä artikkeli on suunnattu ihmisille, joilla on jo ollut ensimmäinen lähestymistapa Reactiin ja joilla aloittelijoina on epäilyksiä siitä, miten se setState
toimii ja miten sitä käytetään oikein. Sen pitäisi myös auttaa keski- ja vanhempi-kehittäjiä käyttämään puhtaampia ja abstraktimpia tapoja asettaa tila ja saada korkeamman asteen funktiot käsittelemään ja abstraktissa tilassa.
Vain lukea ja pitää hauskaa!
Tartu siis kuppi kahvia ja jatka lukemista! ?
SetState (): n peruskäsitteet
React Components antaa sinun jakaa käyttöliittymä (UI) itsenäisiksi, uudelleenkäytettäviksi paloiksi, jotta voit ajatella kutakin kappaletta erikseen.
Käsitteellisesti komponentit ovat kuin JavaScript-toimintoja. He hyväksyvät mielivaltaiset syötteet (kutsutaan "rekvisiitiksi") ja palauttavat React-elementit, jotka kuvaavat mitä näytöllä pitäisi näkyä.
Jos sinun on annettava käyttäjälle mahdollisuus syöttää jotain tai muuttaa jollain tavalla muuttujia, jotka komponentti saa rekvisiitta, tarvitset setState
.
Ilmoitatko komponentin funktioksi tai luokaksi, se ei saa koskaan muuttaa omia rekvisiittaansa.
Kaikki React-komponentittäytyy toimia kuin puhtaat toiminnot suhteessa rekvisiittaansa. Tämä tarkoittaa toimintoja, jotka eivät koskaan yritä muuttaa tulojaan ja palauttavat aina saman tuloksen samoille tuloille.
Tietenkin sovellusten käyttöliittymät ovat dynaamisia ja muuttuvat ajan myötä. Siksi state
se luotiin.
State
sallii React-komponenttien muuttaa tuotostaan ajan mittaan vastauksena käyttäjän toimiin, verkon vastauksiin ja muuhun rikkomatta tätä sääntöä.
Luokkiksi määritellyillä komponenteilla on joitain lisäominaisuuksia. Paikallinen tila on ominaisuus, joka on käytettävissä vain luokan komponenteille.
setState
on kirjaston mukana toimitettu API-menetelmä, jotta käyttäjä pystyy määrittelemään ja käsittelemään tilaa ajan myötä.
Kolme peukalon sääntöä, kun käytät setState ()
Älä muokkaa tilaa suoraan

Tilapäivitykset voivat olla asynkronisia
React voi erittää useita setState()
puheluja yhdeksi päivitykseksi suorituskyvyn takaamiseksi.
Koska this.props
ja this.state
sitä voidaan päivittää asynkronisesti, sinun ei pitäisi luottaa heidän arvoihinsa seuraavan tilan laskemisessa.

Sinun tulisi aina tehdä tällaista manipulointia toiminnallista lähestymistapaa, joka toimittaa state
ja props
ja palauttamalla uuden state
perustuu aikaisempaan.
Tilapäivitykset yhdistetään
Kun soitat setState()
, React sulauttaa antamasi objektin nykyiseen state
.
Alla olevassa esimerkissä päivitämme muuttujan dogNeedsVaccination
muista state
muuttujista riippumatta .
Yhdistäminen on matalaa, joten this.setState({ dogNeedsVaccination: true })
muut muuttujat jäävät ehjiksi korvaamalla vain arvon dogNeedsVaccination
.

Noudata tietovirtaa ja vältä ilmoittamasta enimmäisarvoa
Tiedot virtaavat alas! Kumpikaan vanhempien tai lasten komponentit eivät voi tietää, onko tietty komponentti valtiollinen vai kansalaisuudeton, eikä heidän pitäisi olla kiinnostuneita siitä, onko se määritelty funktioksi vai luokaksi.
Siksi state
sitä kutsutaan usein paikalliseksi tai kapseloiduksi. Sitä ei voi käyttää muulla komponentilla kuin sillä, joka omistaa ja asettaa sen.
Kun olet setState
rekvisiitta ja käytät sitä komponentissasi, rikkot renderöintipotkurien virtauksen. Jos jostain syystä komponenttiisi siirretty rekvisiitta muuttui vanhemmassa komponentissa, lapsi ei renderöity automaattisesti maagisesti?
Tarkistetaan esimerkki:

Täällä sinulla on Home
komponentti, joka luo maagisen luvun joka 1000ms ja asettaa sen omaksi state
.
Sen jälkeen se renderöi numeron ja kutsuu kolme Child
komponenttia (sisarusta), jotka saavat maagisen numeron tavoitteenaan näyttää se kolmella eri lähestymistavalla:
Ensimmäinen lähestymistapa
Komponentti ChildOfHome
kunnioittaa React-rekvisiittaisen kaskadivirtausta, ja kun otetaan huomioon, että tavoitteena on vain näyttää maaginen numero, se renderoi props
vastaanotetun suoraan.

Toinen lähestymistapa
Komponentti ChildOfHomeBrother
vastaanottaa props
vanhemmaltaan ja componentDidMount
asettaa vetoamalla taianumeron state
. Sitten se tekee state.magicNumber
.
Tämä esimerkki ei toimi, koska render()
ei tiedä, että a prop
on muuttunut, joten se ei käynnistä komponentin uudelleenhahmonnusta. Koska komponenttia ei enää renderöidä, componentDidMount
sitä ei kutsuta eikä näyttöä päivitetä.

Kolmas lähestymistapa
Yleensä kun yritämme saada sen toimimaan toisella lähestymistavalla, luulemme, että jotain puuttuu. Sen sijaan, että ottaisimme askeleen taaksepäin, lisätään koodiin tavaraa, jotta se toimisi!
Joten tässä kolmannessa lähestymistavassa olemme lisänneet componentDidUpdate
tarkistaaksemme, onko props
komponentin uudelleen renderoinnin käynnistämisessä muutoksia . Tämä on tarpeetonta ja johtaa meidät epäpuhtaaseen koodiin. Se tuo mukanaan myös suorituskykykustannukset, jotka kerrotaan kertojen määrällä, kun teemme tämän isossa sovelluksessa, jossa meillä on paljon ketjutettuja komponentteja ja sivuvaikutuksia.
Tämä on väärin, ellei sinun tarvitse antaa käyttäjän muuttaa vastaanotettua prop-arvoa.
Jos sinun ei tarvitse muuttaa potkuriarvoa, yritä pitää asiat toimimaan React-virtauksen (First Approach) mukaisesti.
Voit tarkistaa toimivan verkkosivun tällä esimerkillä, jonka olen valmistellut sinulle Glitchissä. Katso ja pidä hauskaa?
Katso myös koodi artikkelista Home.js
ja HomeCodeCleaned.js
(ilman HTML-juttuja) repo-artikkelissani.
Kuinka asettaaState
Joten tässä vaiheessa luulen, että on aika likaista kätemme!
Pelataan vähän setState
ja parannetaan sitä! Seuraa vain ja tartu toiseen kupilliseen kahvia!
Luodaan pieni lomake käyttäjätietojen päivittämiseksi:

Tässä on yllä olevan esimerkin koodi:

Asetamme state
kohteeksi, eikä siinä ole ongelmaa, koska nykyinen tilamme ei riipu viimeisestä tilastamme.
Entä jos luomme vielä yhden lomakekentän esittelemään ja näyttämään sukunimen?


Kiva! Olemme tiivistäneet handleFormChange
menetelmän voidaksemme käsitellä kaikkia syöttökenttiä ja setState
.
Entä jos lisäämme vaihtopainikkeen tietojen merkitsemiseksi kelvollisiksi tai virheellisiksi ja laskurin, jotta tiedämme kuinka monta muutosta tilaan on tehty?


Joo! Me rokkaamme! Olemme tiivistäneet paljon tavaraa!
Hmmm ... Oletetaan, että en halua valintaruudun ohjaavan isValid
muuttujaa, vaan yksinkertaisen vaihtopainikkeen.
Erotetaan myös laskurin käsittelijä tästä menetelmästä. Se toimii hyvin, mutta monimutkaisemmissa tilanteissa, joissa React tarvitsee erä- / ryhmämuutoksia, ei ole hyvä käytäntö luottaa this.state.counter
muuttujaan lisäämällä yksi. Tämä arvo voi muuttua sinun tietämättäsi siitä.
Käytämme matalaa kopiota siitä hetkestä, kun operaatio käynnistetään, ja sinä tiettynä ajankohtana et tiedä, onko sen arvo odottamasi vai ei!
Mennään vähän toimiva!


Okei - Olemme menettäneet abstraktion, koska olemme erottaneet käsittelijät, mutta se on hyvästä syystä!
Joten tällä hetkellä pidämme handleFormChange
objektin välittämisen setState
API-menetelmälle. Mutta handleCounter
ja handleIsValid
-menetelmät ovat nyt toimivia ja alkavat tarttumalla nykyiseen tilaan ja muuttamalla sitten tilasta riippuen seuraavaan.
Tämä on oikea tapa muuttaa state
edellisestä tilasta riippuvia muuttujia.
Entä jos haluamme console.log()
ilmoittaa muutokset firstName
ja lastName
syöttölomakkeet aina, kun muutos tapahtuu? Annetaan sille mahdollisuus!

Kiva! Joka kerta, kun tämä handleFormChange
tapahtuu (mikä tarkoittaa uuden näppäimen painamista), logFields()
menetelmä kutsutaan ja kirjaa nykyinen tila konsoliin!
Tarkistetaan selainkonsoli:

Odota! Mitä täällä tapahtui, ihmiset? Konsoliloki on yksi muutos ennen nykyistä lomakesyöttöä! Miksi tämä tapahtuu?
setState on asynkronoitu!
Tiesimme jo tämän, mutta nyt näemme sen silmillämme! Mitä siellä tapahtuu? Katsotaanpa edellä olevia handleFormChange
ja logFields
menetelmiä.
Joten handleFormChange
menetelmä vastaanottaa tapahtuman nimen ja arvon, tekee sitten a setState
näistä tiedoista. Sitten se kutsuu handleCounter
päivittämään laskuritiedot ja lopulta vetoaa logFields
menetelmään. logFields
Menetelmä tarttuu currentState
ja palaa 'Eduard' eikä 'Eduardo'.
Asia on: setState
on asynkronoitu eikä toimi tällä hetkellä. React tekee työnsä ja suorittaa logFields
menetelmän ensin ja lähtee setState
seuraavaan tapahtumasilmukkaan.
Mutta miten voimme välttää tällaisen tilanteen?
No, setState
API: lla on callback
välttää tämä tilanne:

Jos haluamme, että logFields()
otetaan huomioon äskettäiset muutokset, jotka olemme tehneet osavaltioon, meidän on käytettävä sitä takaisinsoiton sisällä seuraavasti:

Okei, nyt se toimii!
Sanomme Reactille: “Hei, reagoi! Varo, että kun käytät logFields
menetelmää, haluan, että sinulla on state
jo päivitetty kunnossa? Luotan sinuun!"
React sanoo: “Okei Edo! Aion hoitaa kaiken tämän erän tavaraa yleensä teen takapihalla kanssa setState
juttu ja vain kun olen valmis, että minä vedota logFields()
! Siisti mies! Rentoutua!"

Ja itse asiassa - se toimi!
Okei kaikille! Tähän mennessä olemme käsitelleet suurimmat sudenkuopat setState
.
Onko sinulla rohkeutta mennä muurin ulkopuolelle? Tartu kuppi kahvia ja saatetaan todella kewl ...
Fancy with setState () -sovellus
Nyt kun meillä on handleCounter
ja handleIsValid
menetelmät ja setState()
ilmaistu funktioilla, voimme laatia tilapäivityksen muilla toiminnoilla! Me likez sävellys! Pidetään hauskaa!

Voimme viedä sisäisen logiikan setState
luokan komponentin ulkopuoliseen toimintoon. Kutsutaan sitä toggleIsValid
. ☝️

Nyt tämä toiminto voi elää luokan osan ulkopuolella, missä tahansa sovelluksessasi.
Entä jos käytämme korkeamman asteen toimintoa?

Vau! Nyt emme toggleIsValid
enää käytä toimintoa. Käynnistämme kutsutun abstraktin korkeamman asteen funktion toggleKey
ja välitämme avaimen (merkkijono tässä tapauksessa) siihen.
Kuinka meidän on muutettava toggleIsValid
toimintoa nyt?

Mitä?! Nyt meillä on funktio nimeltä, toggleKey
joka vastaanottaa key
ja palauttaa uuden funktion, joka muuttaa tilaa toimitetun avaimen mukaan.
Tämä toggleKey
voi olla kirjastossa tai auttajatiedostossa. Sitä voidaan käyttää monissa erilaisissa yhteyksissä muuttaaksesi haluamasi tilan päinvastaiseen.
Loistava!
Tehdään sama inkrementtilaskurin kanssa:


Joo! Se toimii! Niin kiva. Hullutetaan nyt ...
Kuun ammunta ja paluu
Entä jos luomme yleisen makeUpdater
funktion, joka vastaanottaa muunnosfunktion, jota haluat käyttää, ottaa avaimen ja palauttaa tilafunktion, joka hallitsee tilaa muunnosfunktiolla ja avaimella? Hieman hämmentynyt? Mennään!

Ok, se riittää ... Pysähdymme tässä. ?
Voit tarkistaa kaiken tekemämme koodin tässä GitHub-repossa.
Viimeinen mutta ei vähäisin
Älä unohda välttää enimmäistilaa ja kunnioittaa React-renderöintitarvikkeiden kaskadia.
Älä unohda setState
on asynkronoitu.
Älä unohda setState
voi ottaa objektin tai toiminnon
Älä unohda, että sinun pitäisi siirtää funktio, kun seuraava tila riippuu edellisestä tilastasi.
Bibliografia
- Reagoi dokumentaatioon
- Ryan Firenzen Reach Tech -kurssit, joita suosittelen todella.
Kiitos paljon!