Kako postati profesionalac s React setState () za 10 minuta

Ovaj je članak namijenjen ljudima koji su već imali prvi pristup Reactu i koji kao početnici sumnjaju u to kako setStatefunkcionira i kako ga ispravno koristiti. Također bi trebao pomoći srednjim i starijim programerima da koriste čistije i apstraktnije načine postavljanja stanja i čine funkcije viših redova rukovanjem i apstraktnim stanjem.

Samo čitajte i zabavite se!

Zato uzmite šalicu kave i nastavite čitati! ?

Osnovni koncepti setState ()

React Components omogućuju vam da podijelite korisničko sučelje (UI) na neovisne dijelove koji se mogu ponovno koristiti, tako da o svakom komadu možete razmišljati izolirano.

Konceptualno, komponente su poput JavaScript funkcija. Prihvaćaju proizvoljne ulaze (nazvane "rekviziti") i vraćaju React elemente koji opisuju što bi se trebalo pojaviti na ekranu.

Ako trebate dati korisniku priliku da nešto unese ili na neki način promijeni varijable koje komponenta prima kao rekvizite, trebat će vam setState.

Bilo da deklarirate komponentu kao funkciju ili klasu, ona nikada ne smije mijenjati vlastiti rekvizit.

Sve reakcijske komponentemoraju se ponašati kao čiste funkcije s obzirom na svoje rekvizite. To znači funkcije koje nikada ne pokušavaju promijeniti svoje ulaze i uvijek vraćaju isti rezultat za iste ulaze.

Naravno, korisnička sučelja aplikacije su dinamična i mijenjaju se tijekom vremena. Zato stateje stvoreno.

State omogućuje React komponentama da tijekom vremena mijenjaju svoj izlaz kao odgovor na radnje korisnika, mrežne odgovore i bilo što drugo, bez kršenja ovog pravila.

Komponente definirane kao klase imaju neke dodatne značajke. Lokalno stanje je značajka dostupna samo razrednim komponentama.

setState je API metoda koja se isporučuje s knjižnicom tako da korisnik može definirati i manipulirati stanjem tijekom vremena.

Tri pravila palca prilikom upotrebe setState ()

Nemojte izravno mijenjati državu

Ažuriranja država mogu biti asinkrona

React može grupirati više setState()poziva u jedno ažuriranje radi izvedbe.

Zato this.props i this.statemože se ažurirati asinkrono, da ne bi trebali oslanjati na njihove vrijednosti za izračun sljedeće stanje.

Uvijek biste trebali napraviti ovu vrstu manipulacije s funkcionalnim pristupom, stavljanje na raspolaganje statei propste vraća novi statetemelji se na bivše.

Ažuriranja država se spajaju

Kada nazovete setState(), React spaja objekt koji ste unijeli u trenutni state.

U primjeru u nastavku ažuriramo varijablu dogNeedsVaccinationneovisno o ostalim statevarijablama.

Spajanje je plitko, pa this.setState({ dogNeedsVaccination: true }) ostale varijable ostavljaju netaknutima, zamjenjujući samo vrijednost dogNeedsVaccination.

Poštujte protok podataka i izbjegavajte navoditi maks

Podaci teku prema dolje! Ni roditeljske ni podređene komponente ne mogu znati je li određena komponenta sa statusom države ili bez nje, a ne bi ih trebalo zanimati je li definirana kao funkcija ili klasa.

Zato statese često naziva lokalnim ili inkapsuliranim. Nije dostupan nijednoj komponenti osim one koja ga posjeduje i postavlja.

Kada setStatekoristite rekvizit i koristite ga u svojoj komponenti, prekidate tok rekvizita za prikazivanje. Ako se iz nekog razloga propusnica prenesena u vašu komponentu promijeni u nadređenoj komponenti, dijete se neće automatski prikazati automatski-čarobno?!

Provjerimo primjer:

Ovdje imate Homekomponentu koja generira magični broj svakih 1000 ms i postavlja ga u svoj vlastiti state.

Nakon toga generira broj i poziva tri ChildKomponente (braću i sestre) koje će primiti magični broj s ciljem prikazivanja pomoću tri različita pristupa:

Prvi pristup

Komponenta ChildOfHomepoštuje kaskadni tok React rekvizita i, s obzirom na to da je cilj samo prikazati magični broj, propsizravno prikazuje primljeni.

Drugi pristup

Komponenta ChildOfHomeBrotherprima propsod roditelja i, pozivajući se componentDidMount, postavlja čarobni broj u state. Zatim prikazuje state.magicNumber.

Ovaj primjer ne radi jer render()ne zna da se a prop promijenio pa ne pokreće ponovno prikazivanje komponente. Budući da se komponenta više ne prikazuje, componentDidMountne poziva se i zaslon se ne ažurira.

Treći pristup

Obično kada pokušavamo učiniti da to funkcionira koristeći drugi pristup mislimo da nešto nedostaje. Umjesto da se vratimo korak unatrag, nastavljamo dodavati stvari u kôd da bi on funkcionirao!

Dakle, u ovom trećem pristupu dodali smo kako componentDidUpdatebismo provjerili postoji li promjena u propspokretanju ponovnog prikazivanja komponente. To je nepotrebno i vodi nas do nečistog koda. Sa sobom donosi i troškove izvedbe koji će se pomnožiti s brojem puta kada to radimo u velikoj aplikaciji u kojoj imamo puno okovanih komponenata i nuspojava.

To je pogrešno, osim ako ne trebate dopustiti korisniku da promijeni primljenu vrijednost oslonca.

Ako ne trebate mijenjati vrijednost oslonca, uvijek nastojte da stvari rade u skladu s React protokom (prvi pristup).

Možete provjeriti radnu web stranicu s ovim primjerom koji sam vam pripremio u Glitchu. Pogledajte i zabavite se?

Također pogledajte kod u Home.jsi HomeCodeCleaned.js(bez HTML stvari) u mom izvještaju o ovom članku.

Kako postavitiState

U ovom trenutku mislim da je vrijeme da zaprljamo ruke!

Poigrajmo se malo setStatei poboljšajmo to! Samo slijedite i uzmite još jednu šalicu kave!

Stvorimo mali obrazac za ažuriranje korisničkih podataka:

Evo koda za gornji primjer:

Postavljamo statekao objekt i nema problema jer naše trenutno stanje ne ovisi o našem posljednjem stanju.

Što ako stvorimo još jedno polje obrasca za uvođenje i prikaz prezimena?

Lijepo! Apstrahirali smo handleFormChangemetodu kako bismo mogli obrađivati ​​sva polja za unos i setState.

Što ako dodamo preklopni gumb za označavanje podataka kao valjanih ili nevaljanih i brojač da znamo koliko smo promjena izvršili u državi?

Da! Ljuljamo se! Saželi smo puno stvari!

Hmmm ... Recimo da ne želim potvrdni okvir za kontrolu isValidvarijable već jednostavni gumb za prebacivanje.

Odvojimo i obrađivač brojača od ove metode. Djeluje dobro, ali u složenijim situacijama kada React treba skupne / grupne promjene nije dobra politika oslanjati se na this.state.countervarijablu da bi dodala još jednu. Ova se vrijednost može promijeniti, a da vi toga niste svjesni.

Koristimo plitku kopiju istog trenutka kada se operacija pozove i u tom određenom trenutku ne znate je li vrijednost ona koju ste očekivali ili ne!

Krenimo malo funkcionalno!

U redu - Izgubili smo apstrakciju jer smo razdvojili rukovatelje, ali to je iz dobrog razloga!

U ovom trenutku zadržavamo handleFormChangeprosljeđivanje objekta setStateAPI metodi. Ali metode handleCounterand handleIsValidsada su funkcionalne i započinju hvatanjem trenutnog stanja, a zatim ga, ovisno o tom stanju, mijenjaju u sljedeće.

Ovo je ispravan način promjene statevarijabli koje ovise o prethodnom stanju.

Što ako želimo console.log()navesti promjene oblika firstNamei lastNameunosa svaki put kad se promjena dogodi? Pokušajmo!

Lijepo! Svaki put kada se handleFormChangedogodi (što znači da se dogodio novi pritisak na tipku) logFields()metoda se poziva i prijavljuje trenutno stanje u konzolu!

Provjerimo konzolu preglednika:

Čekati! Što se ovdje dogodilo? Dnevnik konzole je jedna promjena prije trenutnog unosa obrasca! Zašto se ovo događa?

setState je asinkroniziran !!

To smo već znali, ali sada to vidimo očima! Što se tamo događa? Pogledajmo gore handleFormChangei logFieldsmetode.

Dakle, handleFormChangemetoda prima ime i vrijednost događaja, a zatim dobiva a setStateod ovih podataka. Zatim poziva handleCounterda ažurira informacije o brojaču i na kraju poziva logFieldsmetodu. logFieldsNačin zgrabi currentStatei vraća „Eduard” umjesto „Eduarda”.

Stvar je u tome što je: setStateasinkroniziran i ne djeluje trenutno. React radi svoj posao i logFieldsprvo izvršava metodu, ostavljajući setStateza sljedeću petlju događaja.

Ali kako možemo izbjeći ovakvu situaciju?

Pa, setStateAPI mora callbackizbjeći ovu situaciju:

Ako želimo logFields()da uzme u obzir nedavne promjene koje smo napravili u državi, moramo je pozvati unutar povratnog poziva, ovako:

Dobro, sad to radi!

Kažemo Reactu: „Hej React! Imajte na umu da, kada pozivate logFieldsmetodu, želim da imate stateveć ažuriranu, u redu? Vjerujem ti!"

React kaže: „U redu Edo! Riješit ću sve stvari koje obično radim u dvorištu sa setStatestvarčicom i tek kad završim s tim, zazvat ću logFields()! Hladnokrvan čovjek! Opustiti!"

I zapravo - uspjelo je!

Ok svi! Do tada smo riješili glavne zamke setState.

Imate li hrabrosti otići dalje od zida? Uzmi šalicu kave i krenimo kewl ...

Stvaranje fantazije s setState ()

Sad kad imamo handleCounteri handleIsValidmetode, a setState()izražene funkcijama, možemo sastaviti ažuriranje stanja s drugim funkcijama! Ja likez sastav! Idemo se zabaviti!

Logiku možemo odvesti u setStatefunkciju izvan komponente klase. Nazovimo to toggleIsValid. ☝️

Sada ova funkcija može živjeti izvan komponente klase, bilo gdje u vašoj aplikaciji.

Što ako koristimo funkciju višeg reda?

Vau! Sad više ne pozivamo toggleIsValidfunkciju. Pozivamo se na apstraktnu funkciju višeg reda koja se zove toggleKeyi u nju prosljeđujemo ključ (u ovom slučaju niz).

Kako trebamo promijeniti toggleIsValidfunkciju sada?

Što?! Sada imamo funkciju koja se naziva toggleKeykoja prima keyi vraća novu funkciju koja mijenja stanje u skladu s isporučenim ključem.

To toggleKeymože biti u knjižnici ili u pomoćnoj datoteci. Na njega se možete pozivati ​​u puno različitih konteksta kako biste promijenili stanje bilo čega što želite u njegovu suprotnost.

Sjajno!

Učinimo isto s obrađivačem brojača priraštaja:

Da! Radi! Tako lijepo. Idemo poludjeti sada ...

Pucanje na Mjesec i povratak

Što ako stvorimo generičku makeUpdaterfunkciju koja prima funkciju transformacije koju želite primijeniti, uzima ključ i vraća funkciju stanja koja upravlja stanjem s funkcijom transformacije i ključem? Malo zbunjen? Idemo!

Ok, dosta je ... Zaustavimo se ovdje. ?

Možete provjeriti sav kod koji smo napravili u ovom GitHub repo-u.

Posljednje, ali ne najmanje

Ne zaboravite izbjegavati maksimalno korištenje i poštujte kaskadno reagiranje rekvizita za prikazivanje.

Ne zaboravite da setStateje async.

Ne zaboravite da setStatemožete uzeti objekt ili funkciju

Ne zaboravite da biste trebali predati funkciju kada vaše sljedeće stanje ovisi o vašem prethodnom stanju.

Bibliografija

  1. Reagirajte na dokumentaciju
  2. Dosegnite tehničke tečajeve Ryana Florencea, koje zaista preporučujem.

Hvala vam puno!