Der useState Hook – Ein umfassender Leitfaden PlatoBlockchain Data Intelligence. Vertikale Suche. Ai.

Der useState-Hook – Eine umfassende Anleitung

Was ist ein Staat?

Bevor wir tief in den useState-Hook eintauchen, wollen wir zunächst den Begriff verstehen Zustand.

Zustand repräsentiert Informationen über etwas zu einem bestimmten Zeitpunkt.

Betrachten wir zum Beispiel ein Textfeld.

Anfangs befindet sich nichts in diesem Textfeld, also ist sein Zustand leer. Angenommen, Sie beginnen mit der Eingabe von Hallo darin, bei jedem Tastendruck ändert sich der Zustand des Textfelds. Zuerst ist es „H“, dann „He“, dann „Hel“ und so weiter, bis es zu „Hello“ wird.

Beachten Sie außerdem, dass Sie während der Eingabe den vorherigen Wert nicht verlieren. Wenn Sie „H“ gefolgt von „e“ drücken, erhalten Sie „He“ und nicht nur „e“. Mit anderen Worten, Sie können sich Staat als den vorstellen Erinnerung des Textfeldes.

Die Notwendigkeit eines Zustands in einer React-Komponente.

Lassen Sie uns dies anhand eines Beispiels verstehen.

Codesanbox ohne Zustand

Hier haben wir a ClickCounter Komponente, die anzeigt, wie oft auf die Inkrement-Schaltfläche geklickt wurde.

Wir benutzen ein lokale Variable „Zähler“ um die Klicks zu zählen.

Jedes Mal, wenn wir auf die Schaltfläche Increment klicken, GriffKlick Funktion wird aufgerufen. Diese Funktion erhöht den Zählerwert um 1 und protokolliert den Wert auch in der Konsole.

Fahren Sie fort, klicken Sie in der CodeSandbox-Vorschau auf die Schaltfläche Increment.

Nichts ist passiert?

Nun, unsere Logik scheint richtig zu sein. Der in der Konsole (CodeSandbox) protokollierte Wert wird bei jedem Klick korrekt aktualisiert, aber warum wird diese Aktualisierung nicht in der Benutzeroberfläche angezeigt?

Das liegt an der Funktionsweise von React.

  • Änderungen an lokalen Variablen lösen kein erneutes Rendern aus.
  • Beim erneuten Rendern wird eine Komponente von Grund auf neu erstellt, dh die Funktion einer Komponente (in diesem Beispiel die ClickCounter-Funktion) wird noch einmal ausgeführt. Da Variablen (z. B. Zähler) für die Funktion lokal sind, gehen ihre vorherigen Werte verloren.

Wie sorgen wir also dafür, dass sich die Komponente Werte zwischen den Rendervorgängen merkt?

Ja, du hast es richtig! Wir tun dies mit Hilfe der useState Haken.

Der useState-Hook

Der Hook useState stellt Mechanismen bereit, um den Zustand beizubehalten und ein erneutes Rendern auszulösen.

Schauen wir uns seine Verwendung an.

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

// OR

const state = React.useState(initialValue);

Der Hook useState gibt ein Array zurück, das zwei Elemente enthält:

  • A Zustandsvariable die ihre Werte während des erneuten Renderns behält. Der an useState übergebene Anfangswert wird der state-Variablen beim ersten Rendern zugewiesen.
  • A Setter-Funktion die die Zustandsvariable aktualisiert und auch ein erneutes Rendern auslöst.
const state = useState(0);
const data = state[0];
const setData = state[1];

Die richtigen Array-Destrukturierung , können wir die obigen Anweisungen in eine einzige Anweisung umwandeln, wie unten gezeigt:

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

Der an useState übergebene Anfangswert wird nur während des ersten Renderns verwendet. Beim erneuten Rendern wird es ignoriert.

Zähler mit useState

Lassen Sie uns nun das frühere Gegenbeispiel aktualisieren, um den useState-Hook einzuschließen.

  • Da wir den Zählerwert zwischen dem erneuten Rendern benötigen, wandeln wir ihn in einen Zustand um.
const [counter, setCounter] = useState(0);
  • Aufruf von setCounter innerhalb der handleClick-Funktion.
const handleClick = () => {
  setCounter(counter + 1);
  console.log(`%c Counter:${counter}`, "color:green");
};

Die setCounter-Funktion aktualisiert den Zählerwert um 1 und löst ein erneutes Rendern aus. Wenn die Funktion der Komponente beim erneuten Rendern aufgerufen wird, hat die von useState zurückgegebene Zustandsvariable den aktualisierten Wert.

Probieren Sie die CodeSandbox mit dem aktualisierten Code aus. Klicken Sie auf die Schaltfläche Increment und sehen Sie die Magie von useState in Aktion.

Codesanbox mit useState

Sie können dies bei einem erneuten Rendern der funktionalen Komponente überprüfen ClickCounter wird durch Anzeigen der Konsolenprotokolle erneut aufgerufen. Das Protokoll „ClickCounter start“, das am Anfang der Komponente hinzugefügt wird, wird bei jedem Rendern protokolliert.

zuerst rendern

neu rendern

Updater-Funktion

Angenommen, wir möchten den Wert von Zähler bei jedem Klick um 4 erhöhen.

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

Angenommen, der Anfangswert des Zählers ist 0. Was erwarten Sie, wenn auf die Schaltfläche geklickt wird?

Ohne Updater-Funktion

Sie haben erwartet, dass die Zählung 4 ist, oder? Aber warum sehen Sie stattdessen 1?

a) Jedes Rendering ist einem Zustand zugeordnet. Der Wert dieses Zustands bleibt für die Lebensdauer dieses Renderings gesperrt.

Beachten Sie, dass das Protokoll in der handleClick-Funktion den Zählerwert als 0 ausgibt.

Egal wie oft Sie die setCounter-Methode aufrufen, der Wert von counter bleibt gleich.

const handleClick = () => {
  setCounter(counter + 1);
    setCounter(counter + 1);
    setCounter(counter + 1);
    setCounter(counter + 1);
    console.log(`%c Counter:${counter}`, "color:green");
    };
b) Bis der gesamte Code in einem Event-Handler ausgeführt ist, löst React kein erneutes Rendern aus.

Aus diesem Grund löst nicht jeder setCounter-Aufruf ein individuelles Rendern aus. Stattdessen fügt React diese Setter-Funktionen in eine Warteschlange ein. Führt sie in der Reihenfolge aus, in der sie in die Warteschlange gestellt wurden. Die Aktualisierungen, die nach dem Ausführen aller Anweisungen am Zustand vorgenommen wurden, spiegeln sich im nächsten Rendering wider. Diese Warteschlange mehrerer Zustandsaktualisierungen wird als bezeichnet Dosierung. Es ermöglicht React, leistungsfähiger zu sein.

Daher erhalten wir hier einen einzelnen Rendering anstelle von 4 verschiedenen Renderings.

Dieses Beispiel ist einfach und Sie können dieses Problem beheben, indem Sie den Code wie unten gezeigt aktualisieren:

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

Aber was wäre, wenn Sie einen Anwendungsfall hätten, bei dem Sie den Status vor dem nächsten Rendern mehrmals aktualisieren möchten?

Dort ist die _ Updater _ Funktion ist praktisch.

Wir können das vorherige Beispiel mit der Updater-Funktion wie folgt umgestalten:

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

Hier vorherigerZähler ⇒ vorherigerZähler + 1 stellt die Updater-Funktion dar.

Wie bereits erläutert, werden diese Updater-Anweisungen ebenfalls in die Warteschlange gestellt (Batching).

Die Aktualisierungsfunktion empfängt einen schwebenden/vorherigen Zustand, den sie verwendet, um den nächsten Zustand zu berechnen.

Updater-Funktions-Batching

Unten ist die CodeSandbox mit der hinzugefügten Updater-Funktion. Versuchen Sie, auf die Inkrement-Schaltfläche zu klicken.

Updater-Funktions-Sandbox

Initialisierungsfunktion

Schauen Sie sich das Beispiel unten an. Hier rufen wir die getItems-Funktion auf, um den Anfangswert für den Status zu erhalten.

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;

Diese Funktion erstellt ein Array mit der Größe 50 und füllt das Array mit Nullen. Siehe das Bild unten.

Array gefüllt mit 50 Nullen

Diese Elemente werden dann auf dem Bildschirm angezeigt.

Alles scheint in Ordnung zu sein, aber wir haben hier ein Problem.

Klicken Sie auf Artikel hinzufügen Schaltfläche (befindet sich hinter der Liste der Elemente), um der Liste ein neues Element hinzuzufügen. Beachten Sie die Protokolle.

Ohne Initialisierungsfunktion

Siehst du hier das Problem?

Das Protokoll „getItems called“ wird jedes Mal zur Konsole hinzugefügt, wenn Sie ein Element hinzufügen. Dies bedeutet, dass diese Funktion bei jedem Rendern aufgerufen wird.

Denken Sie daran, dass useState den ihm nach dem ersten Rendern übergebenen Anfangswert ignoriert, aber hier wird der Anfangswert immer noch neu berechnet. Dies kann teuer werden, wenn wir große Arrays erstellen oder umfangreiche Berechnungen durchführen.

Wir können dieses Problem lösen, indem wir vorbeigehen getItems als _ Initialisierer _ Funktion.

Nehmen wir nun eine kleine Änderung am Code vor.

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

Mit Initialisierungsfunktion

Siehe das Konsolenfenster in CodeSandbox. Beachten Sie, dass das Protokoll „getItems called“ nur beim ersten Rendern gedruckt wird. Wenn nachfolgende Elemente hinzugefügt werden, ist dieses Protokoll nicht vorhanden.

Obwohl es keinen visuellen Unterschied zwischen den beiden Beispielen gibt, unterscheiden sie sich in Bezug auf die Leistung.

Denken Sie daran, wenn Sie eine Funktion für den Anfangszustand benötigen, übergeben Sie die Funktion immer oder rufen Sie die Funktion innerhalb einer anderen Funktion auf. Rufen Sie die Funktion niemals direkt auf.

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

Wie viele useState-Hooks kann ich haben

Sie können so viele useState-Hooks in einer Komponente haben, wie es erforderlich ist.

Siehe die CodeSandbox

Mehrere useState-Hooks

Die folgende Komponente hat drei verschiedene Zustände – Benutzername, Passwort, keepMeSignedIn.

Versuchen Sie, die Werte des Benutzernamens keepMeSignedIn zu aktualisieren. Die aktualisierten Zustände werden in der Konsole protokolliert, wenn auf die Anmeldeschaltfläche geklickt wird.

Highlights

  • useState stellt einen Mechanismus bereit, um ein erneutes Rendern auszulösen und den Zustand zwischen erneutem Rendern beizubehalten.
  • Verwenden Sie die Updater-Funktion, wenn Sie:
    • Berechnen Sie den nächsten Zustand basierend auf dem vorherigen Zustand.
    • Führen Sie vor dem nächsten Rendern mehrere Statusaktualisierungen durch.
  • Wenn der Anfangszustand von einer Funktion abgerufen wird – verwenden Sie die Initialisierungsfunktionssyntax.
  • Innerhalb einer Komponente können mehrere useState-Hooks vorhanden sein.

Gefällt Ihnen dieser Beitrag? Teilen Sie es mit anderen.
Ursprünglich für meinen persönlichen Blog geschrieben – https://gauravsen.com/use-state-hook

Zeitstempel:

Mehr von Codementor React Fakt