Ez a cikk azoknak az embereknek szól, akiknek már volt első megközelítésük a React-hez, és akik kezdőként kételkednek a setState
működésében és a helyes használatában. Segítenie kell a közép- és középkorú fejlesztőknek is az állapot beállításának tisztább és elvontabb módjainak használatában, valamint a magasabb rendű funkciók kezelésében és elvont állapotában.
Csak olvass és érezd jól magad!
Fogjon tehát egy csésze kávét, és olvassa tovább! ?
A setState () alapfogalmai
A React Components lehetővé teszi a felhasználói felület (UI) független, újrafelhasználható darabokra bontását, így minden egyes darabra külön gondolhat.
Fogalmilag az összetevők olyanok, mint a JavaScript funkciók. Elfogadnak tetszőleges bemeneteket (úgynevezett „kellékeket”), és visszaküldik a React elemeket, amelyek leírják, hogy mi jelenjen meg a képernyőn.
Ha meg kell adnia a felhasználónak a lehetőséget, hogy bevegyen valamit, vagy valamilyen módon megváltoztassa azokat a változókat, amelyeket a komponens prop-ként kap, akkor szüksége lesz rá setState
.
Akár egy összetevőt funkcióként, akár osztályként deklarál, soha nem módosíthatja a saját kellékeit.
Minden React komponenskell, hogy tiszta funkciókként működjenek a kellékeik tekintetében. Ez olyan funkciókat jelent, amelyek soha nem próbálják megváltoztatni a bemeneteiket, és ugyanazon bemenetek esetén mindig ugyanazt az eredményt adják vissza.
Természetesen az alkalmazás felhasználói felületei dinamikusak és idővel változnak. Ezért state
jött létre.
State
lehetővé teszi a React összetevők számára, hogy idővel megváltoztassák a kimenetüket a felhasználói műveletekre, a hálózati válaszokra és bármi másra reagálva, anélkül, hogy ezt a szabályt megsértenék.
Osztályként definiált összetevőknek vannak további jellemzőik. A Helyi állapot olyan funkció, amely csak a Class Components számára érhető el.
setState
az az API-módszer, amely a könyvtárral van ellátva, hogy a felhasználó idővel képes legyen meghatározni és manipulálni az állapotot.
Három hüvelykujj-szabály a setState () használatakor
Ne módosítsa az állapotot közvetlenül

Az állapotfrissítések aszinkronok lehetnek
A React setState()
a teljesítmény érdekében több hívást egyetlen frissítésben kötegelhet.
Mivel this.props
és this.state
lehet frissíteni aszinkron, akkor nem hivatkozhat értékek kiszámítására a következő állapotot.

Mindig meg kell csinálni ezt a fajta manipuláció funkcionális megközelítés, ellátó state
és props
és visszatérő az új state
alapján az előbbi.
Az államfrissítések összevonásra kerülnek
Ha telefonál setState()
, válaszolnak egyesítést az objektum az Ön által megadott a jelenlegi state
.
Az alábbi példában a változót dogNeedsVaccination
a többi state
változótól függetlenül frissítjük .
Az összevonás sekély, ezért this.setState({ dogNeedsVaccination: true })
a többi változó sértetlen marad, csak a dogNeedsVaccination
.

Tartsa tiszteletben az adatfolyamot és kerülje a Max
Az adatok lefelé áramlanak! Sem a szülő, sem a gyermek alkotóelemek nem tudhatják, hogy egy bizonyos összetevő állapot nélküli-e vagy hontalan, és nem szabad, hogy érdekelje őket, hogy funkcióként vagy osztályként definiálják-e.
Ezért state
nevezik gyakran helyi vagy kapszulázottnak. A komponensek nem hozzáférhetők, kivéve azt, amelyik birtokolja és beállítja.
Ha setState
egy támaszt használsz és az alkatrészedben használod, akkor megtöröd a renderelő kellékek áramlását. Ha valamilyen oknál fogva megváltozik az összetevőbe átadott támasz a szülői összetevőben, akkor a gyermek nem fog újra varázslatosan megjeleníteni?
Nézzünk meg egy példát:

Itt van egy Home
alkatrész, amely varázslatos számot generál 1000 ms-onként, és beállítja a sajátjába state
.
Ezt követően megjeleníti a számot, és meghív három Child
összetevőt (testvéreket), amelyek megkapják a varázsszámot azzal a céllal, hogy három különböző megközelítéssel jelenítsék meg:
Első megközelítés
Az alkatrész ChildOfHome
tiszteletben tartja a React props kaszkád áramlását, és tekintettel arra, hogy a cél csak a mágikus szám megjelenítése, a props
kapott eredményt közvetlenül adja vissza.

Második megközelítés
Az alkatrész ChildOfHomeBrother
megkapja a props
szülőjétől, és meghívva componentDidMount
beállítja a mágikus számot state
. Aztán megjeleníti a state.magicNumber
.
Ez a példa nem működik, mert render()
nem tudja, hogy az prop
a megváltozott, így nem váltja ki az összetevő újrarenderelését. Mivel az összetevőt már nem renderelik újra, componentDidMount
nem hívják meg, és a kijelző sem frissül.

Harmadik megközelítés
Általában, amikor megpróbáljuk a második megközelítéssel működni, azt gondoljuk, hogy valami hiányzik. Ahelyett, hogy hátralépnénk, folyamatosan hozzáadjuk a kódhoz a dolgokat, hogy működjön!
Tehát ebben a harmadik megközelítésben hozzáadtuk, componentDidUpdate
hogy ellenőrizzük, van-e változás props
az alkatrész újrarendelésének elindításához. Ez felesleges, és tisztátlan kódhoz vezet. Ez magával hozza a teljesítmény költségeit is, amelyeket meg kell szorozni azzal, hogy hányszor tesszük ezt egy nagy alkalmazásban, ahol sok láncolt komponenssel és mellékhatással rendelkezünk.
Ez helytelen, hacsak nem kell engedélyeznie a felhasználónak a kapott prop érték megváltoztatását.
Ha nem kell megváltoztatnia a prop értékét, mindig próbálja meg a dolgokat a React flow (First Approach) szerint működni.
A működő weblapot ellenőrizheti ezzel a példával, amelyet a Glitch-ben készítettem Önnek. Vessen egy pillantást és szórakozzon?
Nézze meg a cikkben található Home.js
és HomeCodeCleaned.js
a HTML kód nélkül található kódot is.
Hogyan állítsuk be az államot
Tehát ezen a ponton szerintem itt az ideje, hogy bepiszkítsuk a kezünket!
Játsszunk egy kicsit setState
és javítsunk ezen! Csak kövesse és ragadjon meg egy csésze kávét!
Hozzunk létre egy kis űrlapot a felhasználói adatok frissítéséhez:

Itt van a fenti példa kódja:

state
Objektumként állítjuk be , és nincs probléma, mert a jelenlegi állapotunk nem függ az utolsó állapotunktól.
Mi van, ha létrehozunk még egy űrlapmezőt a vezetéknév bevezetésére és megjelenítésére?


Szép! Kivontuk a handleFormChange
módszert, hogy kezelni tudjuk az összes beviteli mezőt és setState
.
Mi van, ha felveszünk egy váltógombot az adatok érvényesnek vagy érvénytelennek jelölésére, és egy számlálót, hogy megtudjuk, hány változtatást hajtottunk végre az állapotban?


Igen! Mi ringatózunk! Sok dolgot elvontunk!
Hmmm ... Tegyük fel, hogy nem egy jelölőnégyzetet akarok használni a isValid
változó vezérléséhez, hanem egy egyszerű váltógombot.
Válasszuk el a számláló kezelőjét is ettől a módszertől. Ez jól működik, de bonyolultabb helyzetekben, amikor a React-nek kötegelt / csoportos változásokat kell végrehajtania, nem jó házirend a this.state.counter
változóra támaszkodni, ha még egyet hozzáad. Ez az érték megváltozhat anélkül, hogy tudatában lenne annak.
A művelet meghívásának pillanatában sekély példányt használunk, és abban a bizonyos időpontban nem tudja, hogy az értéke olyan, amire számított vagy sem!
Menjünk egy kicsit funkcionálisan!


Oké - Az absztrakciót elvesztettük, mert szétválasztottuk a kezelőket, de ez jó okkal jár!
Tehát ebben az időben megtartjuk az handleFormChange
objektum továbbítását az setState
API módszerhez. De a handleCounter
és a handleIsValid
módszerek most már működőképesek, és azzal kezdődnek, hogy megragadják az aktuális állapotot, majd attól függően megváltoztatják a következőre.
Ez a helyes módszer state
az előző állapottól függő változók megváltoztatására .
Mi van, ha minden változás bekövetkezésekor meg akarjuk console.log()
állapítani az firstName
és a lastName
beviteli űrlap változását? Próbáljuk meg!

Szép! Valahányszor az handleFormChange
esemény bekövetkezik (ami azt jelenti, hogy új gombnyomás történt) logFields()
, meghívja a módszert, és naplózza az aktuális állapotot a konzolba!
Ellenőrizzük a böngésző konzolt:

Várjon! Mi történt itt, emberek? A konzolnapló egy változás az aktuális űrlapbevitel előtt! Miért történik ez?
A setState async !!
Ezt már tudtuk, de most a szemünkkel látjuk! Mi történik ott? Vessünk egy pillantást a fenti módszerekre handleFormChange
és logFields
módszerekre.
Tehát a handleFormChange
metódus megkapja az esemény nevét és értékét, majd elvégzi setState
ezen adatok egy részét. Ezután felhívja a handleCounter
számláló információ frissítését, és végül meghívja a logFields
módszert. A logFields
módszer megragadja az currentState
'Eduardo' helyett az 'Eduard' szót.
A helyzet: setState
aszinkron, és pillanatnyilag nem cselekszik. A React elvégzi a dolgát, és logFields
először végrehajtja a módszert, setState
a következő esemény ciklusra hagyva .
De hogyan kerülhetjük el az ilyen helyzetet?
Nos, az setState
API-nak van egy, callback
hogy elkerülje ezt a helyzetet:

Ha azt akarjuk logFields()
, hogy az állam figyelembe vegye a közelmúltbeli változásokat, akkor ezt a visszahíváson belül kell meghívnunk, így:

Oké, most már működik!
Azt mondjuk a React-nek: „Hé, reagálj! Vigyázzon, hogy amikor meghívja a logFields
módszert, azt akarom, hogy a state
már frissített rendben legyen? Bízom benned!"
React azt mondja: „Oké Edo! Kezelni fogom ezt a sok cuccot, amit általában a hátsó udvarban végzek a dologgal, setState
és csak akkor, amikor ezzel végzek, meghívom logFields()
! Jó fej! Pihenjen!

És ami azt illeti - bevált!
Oké mindenkinek! Ekkor már megoldottuk a legfontosabb buktatókat setState
.
Van bátorsága túlmenni a falon? Fogj egy csésze kávét, és vegyünk egy csomót
Divat a setState () használatával
Most, hogy rendelkezünk handleCounter
és handleIsValid
metódusokkal, valamint setState()
függvényekkel kifejezve, összeállíthatjuk az állapotfrissítést más függvényekkel! Me likez kompozíció! Érezzük jól magunkat!

Átvihetjük a belsejében lévő logikát setState
az osztálykomponensen kívüli függvénybe. Nevezzük toggleIsValid
. ☝️

Most ez a funkció élhet az osztály összetevőjén kívül, bárhol az alkalmazásban.
Mi van, ha magasabb rendű függvényt használunk?

Azta! Most már nem hívjuk meg a toggleIsValid
funkciót. Meghívunk egy absztrakt magasabb rendű függvényt, amelyet toggleKey
meghívunk, és átadunk egy kulcsot (ebben az esetben stringet).
Hogyan kell toggleIsValid
most megváltoztatnunk a funkciót?

Mit?! Most van egy úgynevezett függvényünk, toggleKey
amely a-t kapja, key
és egy új függvényt ad vissza, amely megváltoztatja az állapotot a mellékelt kulcs szerint.
Ez toggleKey
lehet egy könyvtárban vagy egy segítő fájlban. Nagyon sokféle összefüggésben fel lehet hívni, hogy a kívánt állapotát az ellenkezőjéhez változtassa.
Nagy!
Tegyük ugyanezt az inkrement számlálóval:


Igen! Működik! Olyan szép. Most őrüljünk meg ...
Lövés a Holdra és visszatérés
Mi van, ha létrehozunk egy általános makeUpdater
függvényt, amely megkapja az alkalmazni kívánt transzformációs függvényt, megfogja a kulcsot, és visszaadja az állapotot kezelő állapotfüggvényt a transzformációs függvénnyel és a kulccsal? Kicsit zavart? Gyerünk!

Ok, ez elég ... Álljunk meg itt. ?
Ellenőrizheti az összes kódot, amelyet ebben a GitHub-repóban végeztünk.
Végül, de nem utolsó sorban
Ne felejtse el elkerülni a maximális állapotot, és tiszteletben tartani a React renderelési kellékek kaszkádját.
Ne felejtsd el setState
, hogy aszinkron.
Ne felejtsd el setState
, hogy objektumot vagy funkciót vehet fel
Ne felejtsük el, hogy akkor adja át a függvényt, amikor a következő állapota az előző állapotától függ.
Bibliográfia
- Reagáljon a dokumentációra
- Érje el Ryan Florence technikai tanfolyamait, amelyeket nagyon ajánlok.
Nagyon szépen köszönjük!