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 setStatetoimii 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 statese 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.statesitä 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 stateja propsja palauttamalla uuden stateperustuu aikaisempaan.

Tilapäivitykset yhdistetään

Kun soitat setState(), React sulauttaa antamasi objektin nykyiseen state.

Alla olevassa esimerkissä päivitämme muuttujan dogNeedsVaccinationmuista statemuuttujista 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 statesitä kutsutaan usein paikalliseksi tai kapseloiduksi. Sitä ei voi käyttää muulla komponentilla kuin sillä, joka omistaa ja asettaa sen.

Kun olet setStaterekvisiitta 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 Homekomponentti, joka luo maagisen luvun joka 1000ms ja asettaa sen omaksi state.

Sen jälkeen se renderöi numeron ja kutsuu kolme Childkomponenttia (sisarusta), jotka saavat maagisen numeron tavoitteenaan näyttää se kolmella eri lähestymistavalla:

Ensimmäinen lähestymistapa

Komponentti ChildOfHomekunnioittaa React-rekvisiittaisen kaskadivirtausta, ja kun otetaan huomioon, että tavoitteena on vain näyttää maaginen numero, se renderoi propsvastaanotetun suoraan.

Toinen lähestymistapa

Komponentti ChildOfHomeBrothervastaanottaa propsvanhemmaltaan ja componentDidMountasettaa 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ä, componentDidMountsitä 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 componentDidUpdatetarkistaaksemme, onko propskomponentin 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.jsja HomeCodeCleaned.js(ilman HTML-juttuja) repo-artikkelissani.

Kuinka asettaaState

Joten tässä vaiheessa luulen, että on aika likaista kätemme!

Pelataan vähän setStateja 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 statekohteeksi, 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 handleFormChangemenetelmä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 isValidmuuttujaa, 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.countermuuttujaan 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 handleFormChangeobjektin välittämisen setStateAPI-menetelmälle. Mutta handleCounterja handleIsValid-menetelmät ovat nyt toimivia ja alkavat tarttumalla nykyiseen tilaan ja muuttamalla sitten tilasta riippuen seuraavaan.

Tämä on oikea tapa muuttaa stateedellisestä tilasta riippuvia muuttujia.

Entä jos haluamme console.log()ilmoittaa muutokset firstNameja lastNamesyöttölomakkeet aina, kun muutos tapahtuu? Annetaan sille mahdollisuus!

Kiva! Joka kerta, kun tämä handleFormChangetapahtuu (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 handleFormChangeja logFieldsmenetelmiä.

Joten handleFormChangemenetelmä vastaanottaa tapahtuman nimen ja arvon, tekee sitten a setStatenäistä tiedoista. Sitten se kutsuu handleCounterpäivittämään laskuritiedot ja lopulta vetoaa logFieldsmenetelmään. logFieldsMenetelmä tarttuu currentStateja palaa 'Eduard' eikä 'Eduardo'.

Asia on: setStateon asynkronoitu eikä toimi tällä hetkellä. React tekee työnsä ja suorittaa logFieldsmenetelmän ensin ja lähtee setStateseuraavaan tapahtumasilmukkaan.

Mutta miten voimme välttää tällaisen tilanteen?

No, setStateAPI: lla on callbackvä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 logFieldsmenetelmää, haluan, että sinulla on statejo päivitetty kunnossa? Luotan sinuun!"

React sanoo: “Okei Edo! Aion hoitaa kaiken tämän erän tavaraa yleensä teen takapihalla kanssa setStatejuttu 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 handleCounterja handleIsValidmenetelmät ja setState()ilmaistu funktioilla, voimme laatia tilapäivityksen muilla toiminnoilla! Me likez sävellys! Pidetään hauskaa!

Voimme viedä sisäisen logiikan setStateluokan 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 toggleIsValidenää käytä toimintoa. Käynnistämme kutsutun abstraktin korkeamman asteen funktion toggleKeyja välitämme avaimen (merkkijono tässä tapauksessa) siihen.

Kuinka meidän on muutettava toggleIsValidtoimintoa nyt?

Mitä?! Nyt meillä on funktio nimeltä, toggleKeyjoka vastaanottaa keyja palauttaa uuden funktion, joka muuttaa tilaa toimitetun avaimen mukaan.

Tämä toggleKeyvoi 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 makeUpdaterfunktion, 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 setStateon asynkronoitu.

Älä unohda setStatevoi ottaa objektin tai toiminnon

Älä unohda, että sinun pitäisi siirtää funktio, kun seuraava tila riippuu edellisestä tilastasi.

Bibliografia

  1. Reagoi dokumentaatioon
  2. Ryan Firenzen Reach Tech -kurssit, joita suosittelen todella.

Kiitos paljon!