UseState hook – PlatoBlockchaini andmeanalüüsi põhjalik juhend. Vertikaalne otsing. Ai.

UseState hook – põhjalik juhend

Mis on riik?

Enne kui sukeldume sügavale oleku konksu kasutamisesse, mõistkem kõigepealt mõistet riik.

Olek esindab teavet millegi kohta antud ajahetkel.

Näiteks vaatleme tekstikasti.

Esialgu pole selle tekstikasti sees midagi, seega on selle olek tühi. Oletame, et hakkate selle sisse tippima Hello, iga klahvivajutuse korral muutub tekstikasti olek. Algul on see “H”, siis “He”, siis “Hel” ja nii edasi, kuni see muutub “Tere”.

Samuti pange tähele, et tippimisel ei kaota te eelmist väärtust. Kui vajutate "H", millele järgneb "e", saate "He", mitte ainult "e". Teisisõnu võite osariigist mõelda kui mälu tekstikastist.

Vajadus oleku järele Reacti komponendis.

Mõistame seda näite abil.

Codesanbox ilma olekuta

Siin on meil a Klõpsake loendurit komponent, mis kuvab nupu Kasvatamine klõpsamiste arvu.

Me kasutame a kohalik muutuja "loendur" klikkide arvu pidamiseks.

Iga kord, kui klõpsame nuppu Suurenda, käepideKlõpsake funktsioon käivitatakse. See funktsioon suurendab loenduri väärtust 1 võrra ja logib väärtuse ka konsoolis.

Jätkake, klõpsake CodeSandboxi eelvaates nuppu Kasv.

Midagi ei juhtunud?

Meie loogika näib olevat õige. Konsooli (CodeSandbox) logitud väärtus värskendatakse õigesti iga kord, kui klõpsame, kuid miks see värskendus kasutajaliideses ei kajastu?

Selle põhjuseks on Reacti toimimisviis.

  • Kohalike muutujate muudatused ei käivita uuesti renderdamist.
  • Ümberrenderduse käigus luuakse komponent nullist, st komponendi funktsioon (selles näites on see ClickCounter) käivitatakse uuesti. Kuna muutujad (nt loendur) on funktsiooni lokaalsed, lähevad nende varasemad väärtused kaotsi.

Niisiis, kuidas panna komponent renderduste vahel väärtusi meeles pidama?

Jah, sa said õigesti aru! Teeme seda abiga useState konks.

UseState konks

Konks useState pakub mehhanisme oleku säilitamiseks ja uuesti renderdamise käivitamiseks.

Vaatame selle kasutamist.

import React, { useState } from "react";
const state = useState(initialValue);

// OR

const state = React.useState(initialValue);

Konks useState tagastab massiivi, mis sisaldab kahte üksust:

  • A oleku muutuja mis säilitab oma väärtused uuesti renderdamise ajal. UseState'ile edastatud algväärtus määratakse olekumuutujale esimese renderduse ajal.
  • A seadja funktsioon mis värskendab olekumuutujat ja käivitab ka uuesti renderdamise.
const state = useState(0);
const data = state[0];
const setData = state[1];

Kasutamine massiivi destruktureerimine , saame ülaltoodud väited ümber kujundada üheks lauseks, nagu allpool näidatud:

const [data, setData] = useState(0);

UseState'ile edastatud algväärtust kasutatakse ainult esimese renderduse ajal. Uuesti renderdamisel seda ignoreeritakse.

Loendur koos useState'iga

Nüüd värskendame varasemat loenduri näidet, et see hõlmaks konksu useState.

  • Kuna me vajame kordusrenderdamiste vahel loenduri väärtust, teisendame selle olekuks.
const [counter, setCounter] = useState(0);
  • Helistamine setCounterile HandiClick funktsiooni sees.
const handleClick = () => {
  setCounter(counter + 1);
  console.log(`%c Counter:${counter}`, "color:green");
};

Funktsioon setCounter värskendab loenduri väärtust 1 võrra ja käivitab uuesti renderdamise. Kui komponendi funktsiooni uuesti renderdatakse, on useState'i tagastatud olekumuutujal värskendatud väärtus.

Proovige CodeSandboxi värskendatud koodiga. Klõpsake nuppu Suurenda ja vaadake, kuidas useState toimib.

Codesanbox koos useState'iga

Saate seda kontrollida funktsionaalse komponendi uuesti renderdamisel Klõpsake loendurit kutsutakse uuesti, vaadates konsooli logisid. Logi "ClickCounter start", mis lisatakse komponendi algusesse, logitakse igale renderdusele.

esimene renderdamine

uuesti renderdada

Uuendaja funktsioon

Oletame, et tahame iga klõpsu korral loenduri väärtust 4 võrra suurendada.

const handleClick = () => {
  setCounter(counter + 1);
    setCounter(counter + 1);
    setCounter(counter + 1);
    setCounter(counter + 1);
    console.log(`%c Counter:${counter}`, "color:green");
    };

Oletame, et loenduri algväärtus on 0. Mida te ootate pärast nupu klõpsamist näha?

Ilma värskendaja funktsioonita

Kas sa eeldasid, et arv on 4, eks? Aga miks sa näed selle asemel 1?

a) Iga renderdus on seotud olekuga. Selle oleku väärtus jääb selle renderdamise eluea jooksul lukustatuks.

Pange tähele, et HandClick funktsiooni sees olev logi prindib loenduri väärtuseks 0.

Ükskõik kui mitu korda setCounteri meetodit kutsute, jääb loenduri väärtus samaks.

const handleClick = () => {
  setCounter(counter + 1);
    setCounter(counter + 1);
    setCounter(counter + 1);
    setCounter(counter + 1);
    console.log(`%c Counter:${counter}`, "color:green");
    };
b) Kuni kogu sündmuste käitleja sees olev kood pole käivitatud, ei käivita React uuesti renderdamist.

Sel põhjusel ei käivita iga setCounteri kutse eraldi renderdust. Selle asemel lisab React need seadistusfunktsioonid järjekorda. Täidab need järjekorda pandud järjekorras. Pärast kõigi avalduste täitmist olekusse tehtud värskendused kajastuvad järgmises renderduses. Seda mitme olekuvärskenduste järjekorda nimetatakse partii. See võimaldab Reactil olla tulemuslikum.

Seetõttu saame siin nelja erineva renderduse asemel ühe renderduse.

See näide on lihtne ja saate selle probleemi lahendada, värskendades allpool näidatud koodi.

const handleClick = () => {
setCounter(counter + 4);
    console.log(`%c Counter:${counter}`, "color:green");
    };

Aga mis siis, kui teil oli kasutusjuhtum, kus soovite olekut mitu korda enne järgmist renderdamist värskendada.

See on koht, kus _ uuendaja _ funktsioon on mugav.

Eelmist näidet saame värskendaja funktsiooniga ümber kujundada järgmiselt:

const handleClick = () => {
  setCounter(prevCounter => prevCounter + 1);
    setCounter(prevCounter => prevCounter + 1);
    setCounter(prevCounter => prevCounter + 1);
    setCounter(prevCounter => prevCounter + 1);
    console.log(`%c Counter:${counter}`, "color:green");
    };

Siin eelloendur ⇒ eelloendur + 1 tähistab värskendaja funktsiooni.

Nagu varem selgitatud, asetatakse need värskendaja avaldused ka järjekorda (pakkimine).

Uuendaja funktsioon saab ootel/eelmise oleku, mida ta kasutab järgmise oleku arvutamiseks.

Värskendaja funktsioonide komplekteerimine

Allpool on CodeSandbox, millele on lisatud värskendaja funktsioon. Proovige klõpsata suurendamise nuppu.

Uuendaja funktsiooni liivakast

Initsialiseerija funktsioon

Heitke pilk allolevale näitele. Siin kutsume oleku algväärtuse saamiseks funktsiooni getItems.

import React from "react";
import { useState } from "react";
function ListItems() { 
  const getItems = () => { 
    console.log(`%c getItems called`, "color:hotpink");
    	return Array(50).fill(0); 
    }; 
  const [items, setItems] = useState(getItems()); 
    
    return ( 
    	<div className="card">
        <ul> {items.map((item, index) => 
        	( <li key={index}>Item {index + 1}		</li>))} 
        </ul> <button onClick={() => setItems([...items, 0])}>Add Item</button> 	</div> );
} 
export default ListItems;

See funktsioon loob massiivi suurusega 50 ja täidab massiivi nullidega. Vaadake allolevat pilti.

Massiiv täidetud 50 nulliga

Seejärel kuvatakse need üksused ekraanil.

Tundub, et kõik on korras, kuid meil on siin probleem.

Klõpsake Lisa üksus nuppu (asub üksuste loendi järel), et lisada loendisse uus üksus. Jälgige palke.

Ilma initsialiseerimisfunktsioonita

Kas näete siin probleemi?

Logi "getItems callis" lisatakse konsooli iga kord, kui üksuse lisate. See tähendab, et seda funktsiooni kutsutakse välja iga renderduse korral.

Pidage meeles, et useState ignoreerib talle pärast esimest renderdamist edastatud algväärtust, kuid siin arvutatakse algväärtus ikkagi ümber. See võib olla kulukas, kui loome suuri massiive või teeme suuri arvutusi.

Me saame selle probleemi lahendada möödaminnes getItems kui _ initsialiseerija _ funktsioon.

Teeme nüüd koodis väikese muudatuse.

const [items, setItems] = useState(getItems);

Initsialiseerimisfunktsiooniga

Vaadake CodeSandboxis konsooli akent. Pange tähele, et logi "getItems callis" prinditakse ainult esimesel renderdamisel. Järgmiste üksuste lisamisel seda logi seal pole.

Kuigi kahe näite vahel pole visuaalset erinevust, on need toimivuse osas erinevad.

Pidage meeles, kui vajate funktsiooni algoleku jaoks, edastage funktsioon alati või kutsuge funktsioon mõne teise funktsiooni sees. Ärge kunagi helistage funktsioonile otse.

✅ const [items, setItems] = useState(getItems);
✅ const [items, setItems] = useState(() => getItems());
❌ const [items, setItems] = useState(getItems());

Mitu useState konksu mul võib olla

Ühe komponendi sees võib olla nii palju useState konkse, kui see nõuab.

Vaadake CodeSandboxi

Mitmekordne kasutamineState konksud

Alloleval komponendil on kolm erinevat olekut – kasutajanimi, parool, keepMeSignedIn.

Proovige värskendada kasutajanime keepMeSignedIn väärtusi. Värskendatud olekud logitakse sisselogimisnupul klõpsamisel konsooli.

Esiletõstetud

  • useState pakub mehhanismi uuesti renderdamise käivitamiseks ja oleku säilitamiseks kordusrenderdamiste vahel.
  • Kasutage värskendaja funktsiooni, kui teil on vaja:
    • Arvutage järgmine olek eelmise oleku põhjal.
    • Enne järgmist renderdamist tehke olekule mitu värskendust.
  • Kui algseisund saadakse funktsioonist – kasutage lähtestamisfunktsiooni süntaksit.
  • Ühe komponendi sees võib olla mitu useState konksu.

Kas see postitus meeldis? Jaga seda teistega.
Algselt kirjutatud minu isikliku ajaveebi jaoks - https://gauravsen.com/use-state-hook

Ajatempel:

Veel alates Kodeerija reageerimise fakt