De useState hook - Een uitgebreide gids PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

De useState hook – Een uitgebreide gids

Wat is een staat?

Voordat we diep in de useState hook duiken, laten we eerst de term begrijpen staat.

Staat vertegenwoordigt informatie over iets op een bepaald moment in de tijd.

Laten we bijvoorbeeld een tekstvak beschouwen.

In eerste instantie staat er niets in dit tekstvak, dus de status is leeg. Stel dat u Hello erin begint te typen, voor elke toetsaanslag verandert de status van het tekstvak. In het begin is het "H", dan "Hij", dan "Hel" enzovoort totdat het "Hallo" wordt.

Merk ook op dat terwijl u typt, u ​​de vorige waarde niet verliest. Als u op "H" drukt, gevolgd door "e", krijgt u "Hij" en niet alleen "e". Met andere woorden, je kunt de staat zien als de geheugen van het tekstvak.

De behoefte aan status in een React-component.

Laten we dit begrijpen aan de hand van een voorbeeld.

Codesanbox zonder status

Hier hebben we een Klikteller component die het aantal keren weergeeft dat op de knop Increment is geklikt.

We gebruiken een lokale variabele "teller" om de klikken bij te houden.

Elke keer dat we op de knop Verhogen klikken, handvatKlik functie wordt aangeroepen. Deze functie verhoogt de tellerwaarde met 1 en logt ook de waarde in de console.

Ga je gang, klik op de knop Increment in het voorbeeld van CodeSandbox.

Er is niks gebeurd?

Nou, onze logica lijkt te kloppen. De waarde die is vastgelegd in de console (CodeSandbox) wordt elke keer dat we klikken correct bijgewerkt, maar waarom wordt deze update niet weergegeven in de gebruikersinterface?

Het komt door de manier waarop React werkt.

  • Wijzigingen in lokale variabelen leiden niet tot een re-render.
  • Tijdens een re-render wordt een component helemaal opnieuw gemaakt, dwz de functie van een component (in dit voorbeeld is het de ClickCounter-functie) wordt opnieuw uitgevoerd. Omdat variabelen (bijvoorbeeld teller) lokaal zijn voor de functie, gaan hun vorige waarden verloren.

Dus hoe zorgen we ervoor dat de component waarden tussen renders onthoudt?

Ja, je hebt gelijk! Dit doen we met behulp van de gebruikStatus haak.

De useState hook

De useState hook biedt mechanismen om de status te behouden en een re-render te activeren.

Laten we eens kijken naar het gebruik ervan.

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

// OR

const state = React.useState(initialValue);

De useState hook retourneert een array die twee items bevat:

  • A toestandsvariabele die zijn waarden behoudt tijdens opnieuw renderen. De initiële waarde die aan useState wordt doorgegeven, wordt tijdens de eerste render toegewezen aan de variabele state.
  • A setter functie: die de toestandsvariabele bijwerkt en ook een re-render activeert.
const state = useState(0);
const data = state[0];
const setData = state[1];

gebruik array de-structurering , kunnen we de bovenstaande uitspraken herstructureren in één enkele instructie, zoals hieronder weergegeven:

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

De initiële waarde die wordt doorgegeven aan useState wordt alleen gebruikt tijdens de eerste render. Voor opnieuw renderen wordt dit genegeerd.

Teller met useState

Laten we nu het eerdere tellervoorbeeld bijwerken om de useState hook op te nemen.

  • Aangezien we de tellerwaarde tussen re-renders nodig hebben, laten we deze converteren naar een toestand.
const [counter, setCounter] = useState(0);
  • SetCounter aanroepen in de handleClick-functie.
const handleClick = () => {
  setCounter(counter + 1);
  console.log(`%c Counter:${counter}`, "color:green");
};

De setCounter-functie werkt de tellerwaarde bij met 1 en activeert een re-render. Wanneer de functie van de component wordt aangeroepen bij het opnieuw renderen, heeft de state-variabele die wordt geretourneerd door useState de bijgewerkte waarde.

Probeer de CodeSandbox uit met de bijgewerkte code. Klik op de knop Increment en zie de magie van useState in actie.

Codesanbox met useState

U kunt controleren of bij een re-render de functionele component Klikteller wordt opnieuw aangeroepen door de consolelogboeken te bekijken. Het logboek “ClickCounter start” dat aan het begin van de component wordt toegevoegd, wordt bij elke render gelogd.

eerst renderen

opnieuw weergeven

Updater-functie

Stel dat we de waarde van de teller bij elke klik met 4 willen verhogen.

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

Neem aan dat de beginwaarde van de teller 0 is. Wat verwacht u te zien als er op de knop wordt geklikt?

Zonder updater-functie

Je had toch verwacht dat de telling 4 zou zijn? Maar waarom zie je in plaats daarvan 1?

a) Elke weergave is gekoppeld aan een status. De waarde van die status blijft vergrendeld voor de levensduur van die weergave.

Merk op dat het logboek in de handleClick-functie de tellerwaarde als 0 afdrukt.

Het maakt niet uit hoe vaak u de methode setCounter aanroept, de waarde van de teller blijft hetzelfde.

const handleClick = () => {
  setCounter(counter + 1);
    setCounter(counter + 1);
    setCounter(counter + 1);
    setCounter(counter + 1);
    console.log(`%c Counter:${counter}`, "color:green");
    };
b) Totdat alle code in een event-handler is uitgevoerd, zal React geen re-render activeren.

Om deze reden activeert elke setCounter-aanroep geen individuele weergave. In plaats daarvan voegt React deze setterfuncties toe aan een wachtrij. Voert ze uit in de volgorde waarin ze in de wachtrij stonden. De updates die zijn aangebracht in de status nadat alle instructies zijn uitgevoerd, worden weerspiegeld in de volgende weergave. Deze wachtrij van meerdere statusupdates staat bekend als: groeperen. Hierdoor kan React beter presteren.

Daarom krijgen we hier een enkele render in plaats van 4 verschillende renders.

Dit voorbeeld is eenvoudig en u kunt dit probleem oplossen door de code bij te werken zoals hieronder wordt weergegeven:

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

Maar wat als u een use-case had waarbij u de status meerdere keren vóór de volgende render wilde bijwerken.

Dat is waar de _ updater _ functie is handig.

We kunnen het vorige voorbeeld met de updater-functie als volgt refactoren:

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

Here vorigeTeller ⇒ vorigeTeller + 1 vertegenwoordigt de updater-functie.

Zoals eerder uitgelegd, worden deze updater-statements ook in de wachtrij geplaatst (batching).

De updater-functie ontvangt een lopende/vorige status die wordt gebruikt om de volgende status te berekenen.

Updater-functie batching

Hieronder staat de CodeSandbox met de updater-functie toegevoegd. Probeer op de knop Verhogen te klikken.

Updater-functie sandbox

Initialisatiefunctie:

Kijk eens naar het onderstaande voorbeeld. Hier roepen we de functie getItems aan om de beginwaarde voor de status te krijgen.

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;

Deze functie maakt een array met grootte 50 en vult de array met nullen. Raadpleeg de onderstaande afbeelding.

Array gevuld met 50 nullen

Deze items worden vervolgens op het scherm weergegeven.

Alles lijkt in orde te zijn, maar we hebben hier een probleem.

Klik op de Voeg item toe knop (na de lijst met items) om een ​​nieuw item aan de lijst toe te voegen. Let op de logboeken.

Zonder initialisatiefunctie

Zie je het probleem hier?

Het logboek "getItems genaamd" wordt elke keer dat u een item toevoegt aan de console toegevoegd. Dit betekent dat deze functie bij elke render wordt aangeroepen.

Onthoud dat useState de initiële waarde negeert die eraan is doorgegeven na de eerste render, maar hier wordt de initiële waarde nog steeds opnieuw berekend. Dit kan duur zijn als we grote arrays maken of zware berekeningen uitvoeren.

We kunnen dit probleem oplossen door te passeren items ophalen als een _ initialisatie _ functie.

Laten we nu een kleine wijziging in de code aanbrengen.

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

Met initialisatiefunctie

Zie het consolevenster in CodeSandbox. Merk op dat het logboek "getItems genaamd" alleen wordt afgedrukt bij de eerste weergave. Wanneer volgende items worden toegevoegd, is dit logboek er niet.

Hoewel er geen visueel verschil is tussen de twee voorbeelden, zijn ze qua prestaties verschillend.

Onthoud dat wanneer u een functie nodig heeft voor de beginstatus, u altijd de functie moet doorgeven of de functie binnen een andere functie moet aanroepen. Roep de functie nooit rechtstreeks aan.

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

Hoeveel useState hooks kan ik hebben?

U kunt zoveel useState hooks in een component hebben als nodig is.

Zie de CodeSandbox

Meervoudig gebruikState hooks

Het onderstaande onderdeel heeft drie verschillende statussen: gebruikersnaam, wachtwoord, keepMeSignedIn.

Probeer de waarden van gebruikersnaam, keepMeSignedIn, bij te werken. De bijgewerkte statussen worden in de console vastgelegd wanneer op de login-knop wordt geklikt.

Hoogtepunten

  • useState biedt een mechanisme om een ​​re-render te activeren en de toestand tussen re-renders te behouden.
  • Gebruik de updater-functie wanneer u:
    • Bereken de volgende staat op basis van de vorige staat.
    • Voer meerdere updates van de status uit voor de volgende render.
  • Als de initiële status wordt verkregen uit een functie, gebruik dan de syntaxis van de initialisatiefunctie.
  • Er kunnen meerdere useState hooks in een component zitten.

Vind je dit bericht leuk? Deel het met anderen.
Oorspronkelijk geschreven voor mijn persoonlijke blog – https://gauravsen.com/use-state-hook

Tijdstempel:

Meer van Codementor Reageerfeit