Kavelj useState – obsežen vodnik PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Kavelj useState – obsežen vodnik

Kaj je država?

Preden se poglobimo v kavelj useState, najprej razumemo izraz stanje.

Stanje predstavlja informacijo o nečem v danem trenutku.

Na primer, razmislimo o besedilnem polju.

Sprva v tem besedilnem polju ni ničesar, tako da je njegovo stanje prazen. Recimo, da začnete v njem tipkati Hello, z vsakim pritiskom na tipko se stanje besedilnega polja spremeni. Najprej bo "H", nato "On", nato "Hel" in tako naprej, dokler ne postane "Hello".

Upoštevajte tudi, da med tipkanjem ne izgubljate prejšnje vrednosti. Če pritisnete »H« in nato »e«, dobite »He« in ne samo »e«. Z drugimi besedami, lahko si državo predstavljate kot spomin besedilnega polja.

Potreba po stanju v komponenti React.

Razumejmo to s pomočjo primera.

Codesanbox brez stanja

Tukaj imamo ClickCounter komponenta, ki prikazuje, kolikokrat je bil kliknjen gumb Povečaj.

Uporabljamo a lokalna spremenljivka “števec” za štetje klikov.

Vsakič, ko kliknemo gumb Povečaj, handleClick funkcija bo priklicana. Ta funkcija poveča vrednost števca za 1 in zabeleži vrednost v konzoli.

Kar naprej, kliknite gumb Povečaj v predogledu CodeSandbox.

Se ni nič zgodilo?

Zdi se, da je naša logika pravilna. Vrednost, zabeležena v konzoli (CodeSandbox), se pravilno posodobi vsakič, ko kliknemo, toda zakaj se ta posodobitev ne odraža v uporabniškem vmesniku?

To je zaradi načina delovanja Reacta.

  • Spremembe lokalnih spremenljivk ne sprožijo ponovnega upodabljanja.
  • Med ponovnim upodabljanjem se komponenta ustvari iz nič, tj. funkcija komponente (v tem primeru je to funkcija ClickCounter) se znova izvede. Ker so spremenljivke (na primer števec) lokalne za funkcijo, se njihove prejšnje vrednosti izgubijo.

Kako torej poskrbimo, da si komponenta zapomni vrednosti med upodabljanji?

Da, prav ste razumeli! To naredimo s pomočjo useState kavelj.

Kavelj useState

Kavelj useState zagotavlja mehanizme za ohranitev stanja in sprožitev ponovnega upodabljanja.

Poglejmo si njegovo uporabo.

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

// OR

const state = React.useState(initialValue);

Kavelj useState vrne matriko, ki vsebuje dva elementa:

  • A spremenljivka stanja ki med ponovnim upodabljanjem ohrani svoje vrednosti. Začetna vrednost, posredovana useState, je dodeljena spremenljivki stanja med prvim upodabljanjem.
  • A nastavitvena funkcija ki posodobi spremenljivko stanja in tudi sproži ponovno upodabljanje.
const state = useState(0);
const data = state[0];
const setData = state[1];

Uporaba destrukturiranje niza , lahko zgornje izjave predelamo v en sam stavek, kot je prikazano spodaj:

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

Začetna vrednost, posredovana useState, se uporabi samo med prvim upodabljanjem. Pri ponovnem upodabljanju je prezrt.

Števec z useState

Zdaj pa posodobimo prejšnji primer števca, da bo vključeval kljuko useState.

  • Ker potrebujemo vrednost števca med ponovnimi upodabljanji, jo pretvorimo v stanje.
const [counter, setCounter] = useState(0);
  • Klicanje setCounter znotraj funkcije handleClick.
const handleClick = () => {
  setCounter(counter + 1);
  console.log(`%c Counter:${counter}`, "color:green");
};

Funkcija setCounter bo posodobila vrednost števca za 1 in sprožila ponovno upodabljanje. Ko je funkcija komponente poklicana pri ponovnem upodabljanju, bo imela spremenljivka stanja, ki jo vrne useState, posodobljeno vrednost.

Preizkusite CodeSandbox s posodobljeno kodo. Kliknite gumb Povečaj in si oglejte čarovnijo useState v akciji.

Codesanbox z useState

To lahko preverite pri ponovnem upodabljanju funkcionalne komponente ClickCounter se znova pokliče z ogledom dnevnikov konzole. Dnevnik »ClickCounter start«, ki je dodan na začetku komponente, bo zabeležen pri vsakem upodabljanju.

prvi render

ponovno upodabljanje

Funkcija posodabljanja

Recimo, da želimo povečati vrednost števca za 4 na vsak klik.

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

Predpostavimo, da je začetna vrednost števca 0. Kaj pričakujete, da boste videli, ko kliknete gumb?

Brez funkcije posodabljanja

Pričakovali ste, da bo število 4, kajne? Toda zakaj namesto tega vidite 1?

a) Vsaka upodobitev je povezana s stanjem. Vrednost tega stanja ostane zaklenjena za celotno življenjsko dobo tega upodabljanja.

Upoštevajte, da dnevnik znotraj funkcije handleClick natisne vrednost števca kot 0.

Ne glede na to, kolikokrat pokličete metodo setCounter, vrednost števca ostane enaka.

const handleClick = () => {
  setCounter(counter + 1);
    setCounter(counter + 1);
    setCounter(counter + 1);
    setCounter(counter + 1);
    console.log(`%c Counter:${counter}`, "color:green");
    };
b) Dokler se ne izvede vsa koda znotraj obdelovalnika dogodkov, React ne bo sprožil ponovnega upodabljanja.

Iz tega razloga vsak klic setCounter ne sproži posameznega upodabljanja. Namesto tega React doda te nastavitvene funkcije v čakalno vrsto. Izvede jih v vrstnem redu, v katerem so bili v čakalni vrsti. Posodobitve stanja po izvedbi vseh stavkov se odražajo v naslednjem upodabljanju. To čakalno vrsto več posodobitev stanja je znano kot šaržiranje. Reactu omogoča, da je bolj zmogljiv.

Zato tukaj dobimo en sam render namesto 4 različnih upodobitev.

Ta primer je preprost in to težavo lahko odpravite tako, da posodobite kodo, kot je prikazano spodaj:

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

Kaj pa, če bi imeli primer uporabe, ko bi želeli stanje večkrat posodobiti pred naslednjim upodabljanjem.

Tam je _ posodobitve _ funkcija pride prav.

Prejšnji primer lahko preoblikujemo s funkcijo posodabljanja na naslednji način:

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");
    };

Tukaj prevCounter ⇒ prevCounter + 1 predstavlja funkcijo posodabljanja.

Kot je bilo že razloženo, so ti stavki programa za posodabljanje prav tako postavljeni v čakalno vrsto (paket).

Funkcija za posodobitev prejme čakajoče/prejšnje stanje, ki ga uporabi za izračun naslednjega stanja.

Funkcija posodabljanja v serijah

Spodaj je CodeSandbox z dodano funkcijo posodabljanja. Poskusite klikniti gumb za povečanje.

Peskovnik s funkcijo posodobitve

Funkcija inicializatorja

Oglejte si spodnji primer. Tukaj kličemo funkcijo getItems, da dobimo začetno vrednost za stanje.

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;

Ta funkcija ustvari matriko z velikostjo 50 in jo napolni z ničlami. Oglejte si spodnjo sliko.

Matrika, napolnjena s 50 ničlami

Ti elementi se nato prikažejo na zaslonu.

Zdi se, da je vse v redu, vendar imamo tukaj težavo.

Kliknite na Dodaj element gumb (nahaja se za seznamom elementov), ​​da dodate nov element na seznam. Opazujte dnevnike.

Brez funkcije inicializatorja

Ali vidite problem tukaj?

Dnevnik »getItems called« se doda na konzolo vsakič, ko dodate element. To pomeni, da se ta funkcija kliče ob vsakem upodabljanju.

Ne pozabite, da useState ignorira začetno vrednost, ki mu je bila posredovana po prvem upodabljanju, vendar se tukaj začetna vrednost še vedno znova izračuna. To je lahko drago, če ustvarjamo velika polja ali izvajamo težke izračune.

To težavo lahko rešimo s prehodom getItems kot _ inicializator _ funkcijo.

Sedaj pa naredimo majhno spremembo kode.

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

S funkcijo inicializatorja

Oglejte si okno konzole v CodeSandbox. Upoštevajte, da se dnevnik »getItems called« natisne samo pri prvem upodabljanju. Ko so dodani naslednji elementi, tega dnevnika ni.

Čeprav med obema primerkoma ni vizualne razlike, sta si glede zmogljivosti različna.

Ne pozabite, da kadar potrebujete funkcijo za začetno stanje, jo vedno posredujte ali pokličite funkcijo znotraj druge funkcije. Nikoli ne kličite funkcije neposredno.

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

Koliko kavljev useState lahko imam

Znotraj komponente imate lahko toliko kavljev useState, kot jih zahteva.

Oglejte si CodeSandbox

Več kavljev useState

Spodnja komponenta ima tri različna stanja – uporabniško ime, geslo, keepMeSignedIn.

Poskusite posodobiti vrednosti uporabniškega imena, keepMeSignedIn. Posodobljena stanja so zabeležena v konzoli, ko kliknete gumb za prijavo.

Izbor

  • useState zagotavlja mehanizem za sprožitev ponovnega upodabljanja in ohranjanje stanja med ponovnimi upodabljanji.
  • Uporabite funkcijo posodabljanja, ko morate:
    • Naslednje stanje izračunajte na podlagi prejšnjega stanja.
    • Izvedite več posodobitev stanja pred naslednjim upodabljanjem.
  • Če je začetno stanje pridobljeno iz funkcije – uporabite sintakso funkcije inicializatorja.
  • V komponenti je lahko več kavljev useState.

Vam je bila objava všeč? Delite z drugimi.
Prvotno napisano za moj osebni blog – https://gauravsen.com/use-state-hook

Časovni žig:

Več od Codementor React Dejstvo