Maison >interface Web >js tutoriel >Pris dans une fermeture : comprendre les bizarreries de la gestion de l'état de React
Vous êtes-vous déjà demandé pourquoi parfois vos mises à jour d'état React ne fonctionnent pas correctement ? Ou pourquoi cliquer plusieurs fois rapidement sur un bouton ne met pas à jour le compteur comme prévu ? La réponse réside dans la compréhension des fermetures et de la manière dont React gère les mises à jour d'état. Dans cet article, nous dévoilerons ces concepts à l'aide d'exemples simples qui feront que tout s'enclenchera.
Considérez une fermeture comme une fonction qui garde un petit souvenir de son lieu de naissance. C'est comme un instantané polaroïd de toutes les variables qui existaient lors de la création de la fonction. Voyons cela en action avec un simple compteur :
function createPhotoAlbum() { let photoCount = 0; // This is our "snapshot" variable function addPhoto() { photoCount += 1; // This function "remembers" photoCount console.log(`Photos in album: ${photoCount}`); } function getPhotoCount() { console.log(`Current photos: ${photoCount}`); } return { addPhoto, getPhotoCount }; } const myAlbum = createPhotoAlbum(); myAlbum.addPhoto(); // "Photos in album: 1" myAlbum.addPhoto(); // "Photos in album: 2" myAlbum.getPhotoCount() // "Current photos: 2"
Dans cet exemple, les fonctions addPhoto et getPhotoCount mémorisent la variable photoCount, même après la fin de l'exécution de createPhotoAlbum. Il s'agit d'une fermeture en action - des fonctions se souvenant de leur lieu de naissance !
Dans React, les fermetures jouent un rôle crucial dans la façon dont les composants se souviennent de leur état. Voici un composant de compteur simple :
function Counter() { const [count, setCount] = useState(0); const increment = () => { // This function closes over 'count' setCount(count + 1); }; return ( <div> <p>Count: {count}</p> <button onClick={increment}>Add One</button> </div> ); }
La fonction d'incrémentation forme une fermeture autour de la variable d'état de comptage. C'est ainsi qu'il « se souvient » du numéro auquel ajouter lorsque l'on clique sur le bouton.
C'est ici que les choses deviennent intéressantes. Créons une situation où les fermetures peuvent provoquer un comportement inattendu :
function BuggyCounter() { const [count, setCount] = useState(0); const incrementThreeTimes = () => { // All these updates see the same 'count' value! setCount(count + 1); // count is 0 setCount(count + 1); // count is still 0 setCount(count + 1); // count is still 0! }; return ( <div> <p>Count: {count}</p> <button onClick={incrementThreeTimes}>Add Three</button> </div> ); }
Si vous cliquez sur ce bouton, vous pourriez vous attendre à ce que le nombre augmente de 3. Mais surprise ! Il n'augmente que de 1. Cela est dû à une "fermeture obsolète" - notre fonction est bloquée en regardant la valeur d'origine de count lors de sa création.
Pensez-y comme si vous preniez trois photos d'un tableau blanc affichant le chiffre 0, puis essayez d'ajouter 1 à chaque photo. Vous aurez toujours 0 sur chaque photo !
React fournit une solution élégante à ce problème - mises à jour fonctionnelles :
function FixedCounter() { const [count, setCount] = useState(0); const incrementThreeTimes = () => { // Each update builds on the previous one setCount(current => current + 1); // 0 -> 1 setCount(current => current + 1); // 1 -> 2 setCount(current => current + 1); // 2 -> 3 }; return ( <div> <p>Count: {count}</p> <button onClick={incrementThreeTimes}>Add Three</button> </div> ); }
Au lieu d'utiliser la valeur de notre fermeture, nous disons maintenant à React "prenez la valeur actuelle et ajoutez-y une". C'est comme avoir un assistant utile qui regarde toujours le numéro actuel sur le tableau blanc avant de l'ajouter !
Voyons comment cela s'applique à un scénario réel : le bouton J'aime d'une publication sur les réseaux sociaux :
function createPhotoAlbum() { let photoCount = 0; // This is our "snapshot" variable function addPhoto() { photoCount += 1; // This function "remembers" photoCount console.log(`Photos in album: ${photoCount}`); } function getPhotoCount() { console.log(`Current photos: ${photoCount}`); } return { addPhoto, getPhotoCount }; } const myAlbum = createPhotoAlbum(); myAlbum.addPhoto(); // "Photos in album: 1" myAlbum.addPhoto(); // "Photos in album: 2" myAlbum.getPhotoCount() // "Current photos: 2"
Rappel : lors de la mise à jour de l'état en fonction de sa valeur précédente, privilégiez les mises à jour fonctionnelles. C'est comme avoir un assistant fiable qui vérifie toujours la valeur actuelle avant d'apporter des modifications, plutôt que de travailler de mémoire !
Avec ces concepts à votre actif, vous êtes bien équipé pour gérer les mises à jour d'état dans React comme un pro ! Bon codage ! ?
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!