De useState hook van React wordt gebruikt om de statuswaarden van een component op te slaan en UI-updates via re-rendering te triggeren wanneer deze waarden veranderen.
useState veroorzaakt re-rendering van de gehele component, maar minimaliseert daadwerkelijke DOM-wijzigingen door gebruik te maken van de virtuele DOM.
De interne implementatie van useState is gebaseerd op een linked list. Deze lijst koppelt de momenteel renderende component aan de hook, waardoor statuswaarden behouden blijven. Op basis van update-events worden vervolgens andere functies aangeroepen.
Het React-gebied is vreemd genoeg dol op dingen met 'use' ervoor.
Zoals useServer, useCallback, useState, useMemo, etc.
Zelfs aangepaste hooks krijgen allemaal 'use' ervoor.
Waar is dat begonnen?
useState is een bekende hook.
Het slaat een state-waarde op en voert een re-render uit wanneer deze verandert. Het is heel eenvoudig.
Iedereen kent dit voorbeeld.
We zeiden dat er een re-render wordt uitgevoerd wanneer de state-waarde verandert, maar wat is dan precies het bereik van die re-render?
Alleen de p-tag? Of ook de button-tag?
Het juiste antwoord is: de gehele component waarin useState is aangeroepen.
ExampleComponent wordt opnieuw gerenderd, maar...
er wordt gebruikgemaakt van de virtuele DOM om de waarden te vergelijken en alleen de gewijzigde delen van de DOM bij te werken.
useState wordt bij elke re-render aangeroepen, maar hoe blijven de waarden dan behouden?
Het antwoord ligt in de structuur van useState.
De bovenstaande code is de werkelijke useState-code van React.
Het haalt de dispatcher op uit het globale object en roept useState aan.
Hiermee is de structuur echter nog niet helemaal duidelijk.
Als we dieper graven, vinden we de volgende code.
De hook wordt opgehaald en de set-functie wordt direct aan de queue van de hook gebonden.
(bind bindt this aan een bestaande functie, de overige argumenten worden als argumenten voor de functie gebruikt, en er wordt een nieuwe functie geretourneerd met de gebonden this).
Hiermee is de reden nog steeds niet duidelijk.
Laten we nog verder kijken.
We zien dat de init-waarde steeds opnieuw wordt toegewezen. Dit verklaart echter niet hoe de state behouden blijft.
Laten we nog eens kijken. De hook lijkt verdacht.
currentlyRenderingFiber en workInProgressHook zijn globale variabelen.
Er wordt van rechts naar links toegewezen, waardoor een gelinkte lijst wordt gemaakt.
Daarom verwachten we dat de hook de volgende structuur heeft:
Waarden worden aan het begin steeds toegevoegd.
Maar het is nog steeds niet helemaal duidelijk, dus hebben we naar andere implementaties van useState gekeken.
Het bleek dat niet alle implementaties mountState aanroepen, maar bij een re-render updateState en rerenderState gebruiken.
De structuur is dus zoals hierboven beschreven, en er worden verschillende functies aangeroepen op basis van de gebeurtenis.
Als je de code zelf wilt bekijken, kun je naar react/packages/react-reconciler/src/ReactFiberHooks.js gaan.