Der React Hook useState wird verwendet, um den Zustand einer Komponente zu speichern und die Benutzeroberfläche durch Re-Rendering zu aktualisieren, wenn sich der Zustand ändert.
useState führt zwar ein Re-Rendering der gesamten Komponente aus, minimiert aber durch die Verwendung des virtuellen DOM die tatsächlichen DOM-Änderungen.
Die interne Implementierung von useState basiert auf einer verketteten Liste (linked list), die die aktuell gerenderte Komponente und den Hook verbindet, um den Zustandswert beizubehalten und bei Update-Ereignissen verschiedene Funktionen aufzurufen.
Komischerweise ist die React-Community sehr angetan von allem, was mit ‚use‘ beginnt.
useServer, useCallback, useState, useMemo usw.
Auch benutzerdefinierte Hooks verwenden alle ‚use‘.
Wo kommt das her?
useState ist ein bekannter Hook.
Er speichert Zustandswerte und löst ein erneutes Rendern aus, wenn diese sich ändern. Ganz einfach.
Das ist das allseits bekannte Beispiel.
Wenn sich der Zustandswert ändert, wird ein erneutes Rendern ausgelöst. Aber welchen Bereich umfasst dieses erneute Rendern?
Nur das p-Tag? Oder auch das Button-Tag?
Die Antwort ist: die gesamte Komponente, in der useState aufgerufen wurde.
ExampleComponent wird neu gerendert,
aber mithilfe des virtuellen DOMs werden die Werte verglichen und nur die geänderten Bereiche im DOM aktualisiert.
useState wird bei jedem erneuten Rendern aufgerufen. Wie bleiben die Werte erhalten?
Die Antwort ergibt sich aus der Struktur von useState.
Dies ist der tatsächliche React-Code für useState.
Es holt den Dispatcher aus dem globalen Objekt und ruft useState auf.
Daraus lässt sich die Struktur aber nicht verstehen.
Wenn wir tiefer graben, finden wir folgenden Code.
Es holt den Hook ab und bindet die Set-Funktion direkt an die Queue des Hooks.
(bind bindet this an eine bestehende Funktion, die restlichen Argumente werden als Argumente der Funktion verwendet. Anschließend gibt es eine neue Funktion zurück, bei der this gebunden ist).
Auch daraus lässt sich der Grund nicht erschließen.
Lasst uns noch tiefer graben.
Man sieht, dass der Initialisierungswert immer wieder zugewiesen wird. Damit lässt sich die Beibehaltung des Zustands nicht erklären.
Lasst uns noch tiefer graben. Der Hook sieht verdächtig aus.
currentlyRenderingFiber und workInProgressHook sind globale Variablen.
Es wird von rechts nach links zugewiesen, wodurch eine verkettete Liste (Linked List) implementiert wird.
Daher wird die Struktur des Hooks voraussichtlich wie folgt aussehen.
Es werden immer wieder Werte an den Anfang angehängt.
Die Erklärung ist immer noch nicht vollständig. Nachdem ich mir andere Implementierungen von useState angesehen habe,
stellte ich fest, dass nicht immer mountState aufgerufen wird, sondern bei einem erneuten Rendern updateState und rerenderState aufgerufen werden.
Die Struktur ist also wie oben beschrieben und es werden je nach Ereignis verschiedene Funktionen aufgerufen.
Wenn Sie den Code direkt einsehen möchten, finden Sie ihn unter react/packages/react-reconciler/src/ReactFiberHooks.js.