L'hook useState de React est utilisé pour stocker et modifier les valeurs d'état d'un composant, déclenchant une mise à jour de l'interface utilisateur via un rendu.
useState provoque un rendu complet du composant, mais utilise le DOM virtuel pour minimiser les modifications réelles du DOM.
L'implémentation interne de useState est basée sur une liste chaînée, reliant le composant en cours de rendu à l'hook afin de conserver et de mettre à jour les valeurs d'état, et d'appeler une fonction différente en fonction des événements de mise à jour.
Étrangement, l'écosystème React adore les noms de fonctions commençant par "use"
useServer, useCallback, useState, useMemo, etc.
Même les hooks personnalisés commencent par "use"
D'où cela vient-il ?
useState est un hook célèbre.
Il permet de stocker une valeur d'état et de re-rendre le composant lorsque celle-ci change. C'est très simple.
C'est l'exemple que tout le monde connaît.
Lorsqu'une valeur d'état change, le composant est re-rendu, mais quel est l'étendue de ce re-rendu ?
Seulement la balise `
` ? Ou la balise `
La réponse est que c'est le composant `ExampleComponent` entier qui est re-rendu.
Bien que `ExampleComponent` soit re-rendu,
React utilise le DOM virtuel pour comparer les valeurs et ne modifier que les parties du DOM qui ont changé.
useState est appelé à chaque re-rendu, comment les valeurs sont-elles conservées ?
La réponse se trouve dans la structure de `useState`.
Ce code est le code source réel de `useState` dans React.
Il récupère `dispatcher` depuis un objet global et appelle `useState`.
Cela ne permet pas de comprendre la structure.
En creusant plus profondément, on trouve le code suivant :
Il récupère le hook, et crée la fonction `set` en liant directement la file d'attente du hook avec `dispatchSetState`.
(La méthode `bind` permet de lier la valeur de `this` à une fonction existante, et de passer des arguments supplémentaires à cette fonction. Elle renvoie une nouvelle fonction avec `this` lié.)
Il est difficile de comprendre la raison de ce comportement avec ce seul code.
Continuons à explorer.
On peut voir que la valeur initiale est assignée à chaque fois. Cela ne permet pas d'expliquer comment la valeur de l'état est conservée.
Continuons à explorer. Le hook semble suspect.
`currentlyRenderingFiber` et `workInProgressHook` sont des variables globales.
On peut observer que l'ajout se fait de droite à gauche, ce qui permet de mettre en œuvre une liste chaînée.
On peut donc imaginer que la structure du hook est la suivante :
On peut observer que les valeurs sont ajoutées en tête de liste.
L'explication n'est toujours pas claire, j'ai donc examiné d'autres implémentations de `useState`.
Il n'est pas toujours question d'appeler `mountState`, mais plutôt `updateState` et `rerenderState` lors d'un re-rendu.
Par conséquent, la structure est celle décrite ci-dessus et différentes fonctions sont appelées en fonction de l'événement.
Si vous souhaitez consulter le code source, vous pouvez consulter le fichier `react/packages/react-reconciler/src/ReactFiberHooks.js`.