Comment utiliser l’état dans les composants React fonctionnels –
Les composants React peuvent posséder un «état» interne, un ensemble de paires clé-valeur appartenant au composant. Lorsque l’état change, React restitue le composant. Historiquement, l’état ne pouvait être utilisé que dans les composants de classe. À l’aide de hooks, vous pouvez également appliquer l’état aux composants fonctionnels.
Sommaire
L’approche traditionnelle
Les composants de la classe React ont un state
propriété qui tient leur état. Ils fournissent un setState()
méthode que vous pouvez utiliser pour mettre à jour l’état, déclenchant un nouveau rendu.
class MyComponent extends React.Component { state = {value: 1}; this.updateState = () => this.setState({value: (this.state.value + 1)}); render() { return ( <div> <p>{this.state.value}</p> <button onClick={this.updateState}Increment Value</button> </div> ); } }
Dans cet exemple, le texte rendu affichera toujours le nombre dans l’état du composant. Cliquez sur le bouton pour incrémenter la valeur.
Conversion en un composant fonctionnel
Avec un composant aussi simple, il serait idéal de le réécrire en tant que composant fonctionnel. Pour ce faire, vous devrez utiliser le hook useState (). Des crochets ont été ajoutés dans React 16.8; avant cette version, il n’existait aucun mécanisme pour ajouter un état aux composants fonctionnels.
Voici à quoi ressemble le composant ci-dessus en tant que composant fonctionnel:
import React, {useState} from "react"; const MyComponent = () => { const [value, setValue] = useState(1); return ( <div> <p>{value}</p> <button onClick={() => setValue((value + 1))}>Increment Value</button> </div> ); };
C’est plus court et plus lisible que l’original basé sur la classe. Contrairement au composant de classe, vous ne pouvez pas accéder à un state
propriété d’instance ou setState()
méthode. À la place, useState()
est appelé pour configurer l’état et obtenir une fonction de mise à jour.
Anatomie du hook useState ()
Les hooks sont une fonction React qui vous permet de «raccorder» des fonctionnalités à des composants fonctionnels. Comme les fonctions sont pures et n’ont pas d’instances, les capacités initialement implémentées comme React.Component
les méthodes de classe ne peuvent pas être utilisées directement. Les hooks vous permettent d’ajouter ces fonctionnalités aux composants sans avoir à les convertir en classes.
le useState()
hook définit une propriété d’état individuelle. Il renvoie un tableau contenant deux éléments: la valeur de l’état actuel et une fonction que vous pouvez appeler avec une nouvelle valeur pour mettre à jour l’état.
Dans l’exemple, nous utilisons l’affectation de déstructuration de tableau pour décompresser les valeurs du tableau en variables clairement nommées. Par convention, la méthode setter doit être préfixée par set
car il remplace le setState()
méthode de classe.
Appel useState()
déclare une variable d’état, value
dans notre cas, qui sera «préservé» entre les appels de fonction. Cela signifie useState()
est garanti de renvoyer la même valeur chaque fois que vous l’appelez dans votre composant. Toute autre valeur de variable est perdue une fois qu’une fonction se termine; React gère les valeurs d’état en interne pour vous assurer de récupérer la même valeur à chaque exécution de votre fonction.
Mise à jour de l’état
La fonction de mise à jour de l’état n’est qu’une fonction ordinaire. Il est utilisé dans le onClick
handler pour remplacer la valeur de l’état actuel. La gestion interne des valeurs d’état par React garantit que votre composant sera ensuite restitué. useState()
fournira la nouvelle valeur, provoquant le changement d’état.
Il y a une différence importante par rapport au setState()
des composants de classe: programmes de mise à jour d’état fonctionnel remplacer l’État, alors que setState()
fait une fusion superficielle:
const [value, setValue] = useState({foo: "bar", test: {example: "demo"}}); setValue({foo: "foobar"}); // Results in {foo: "foobar"} this.state = {foo: "bar", test: {example: "demo"}}; this.setState({foo: "foobar"}); // Results in {foo: "foobar", test: {example: "demo"}};
Au lieu de passer directement une nouvelle valeur d’état, vous pouvez également confier une fonction aux programmes de mise à jour d’état. Les fonctions reçoivent l’état actuel en tant que paramètre et doivent renvoyer la nouvelle valeur d’état. Ceci est utile lorsque vous travaillez avec des valeurs à bascule.
const Checkbox = () => { const [checked, setChecked] = useState(false); const toggle = previous => !previous; return <input checked={checked} onClick={() => setChecked(toggle)} />; };
Cela vous aide à réutiliser la logique de basculement à plusieurs endroits dans votre composant.
Les valeurs par défaut
Il y a un autre point à noter à propos de useState()
. Le hook lui-même accepte un paramètre qui définit la valeur initiale de la variable d’état. Dans l’exemple ci-dessus, le value
sera initialisé à 1
. Lorsque vous ne spécifiez pas de valeur, undefined
est utilisé. Cela correspond au comportement lors de la configuration du state
propriété d’occurrence dans un composant de classe.
Si vous passez une fonction à useState()
, React l’appellera et utilisera sa valeur de retour comme valeur d’état initiale.
const MyComponent = () => { const initialState = () => 1; const [value, setValue] = useState(initialState); };
Cette technique permet l’initialisation de l’état «paresseux». La fonction ne sera pas appelée tant que React ne sera pas réellement prêt à configurer l’état.
L’utilisation d’une fonction garantit également que la valeur de l’état initial n’est calculée qu’une seule fois. Ceci est important si la détermination de votre état initial nécessite un calcul coûteux – si vous le transmettez directement, la valeur sera calculée à chaque fois que le composant sera rendu, par rapport à une fois lors du premier rendu si vous passez une référence à une fonction.
const MyComponent = () => { const doSomethingExpensive = () => { // ... } const [value, setValue] = useState(doSomethingExpensive()); const [value, setValue] = useState(doSomethingExpensive); };
La différence subtile mais significative entre les deux useState()
les appels illustrent l’amélioration potentielle des performances. La première ligne effectuerait l’opération coûteuse à chaque appel de rendu, même si elle était redondante car l’état était déjà initialisé. Cela ne se produirait pas dans le second cas.
Utilisation de plusieurs valeurs d’état
Vous avez plusieurs choix lorsque vous utilisez plusieurs valeurs d’état dans un seul composant fonctionnel. Vous pouvez revenir à un système de type classe, en utilisant un seul objet stocké dans l’état:
const MyComponent = () => { const [user, setUser] = useState({id: 1, username: "foobar"}); };
Vous auriez besoin de vous assurer d’appeler setUser()
avec l’utilisateur mis à jour objet. La syntaxe de diffusion est pratique de la même manière que les composants de classe:
setUser({...user, username: "example"});
Cela crée un nouvel objet avec les propriétés existantes de user
. Il met ensuite à jour le username
propriété à sa nouvelle valeur. Il est important de créer un Nouveau objet, au lieu de muter directement l’objet existant, la réconciliation d’état de React peut identifier le changement.
Vous pouvez également appeler useState()
plusieurs fois pour configurer des variables d’état uniques pour chaque élément. C’est souvent l’approche préférée pour les composants fonctionnels. Cela peut faciliter la mise à jour des valeurs d’état individuelles.
const MyComponent = () => { const [userId, setUserId] = useState(1); const [username, setUsername] = useState("foobar"); };
Les propriétés avec état ont maintenant leurs propres variables d’état et fonctions de mise à jour.
Conclusion
Réagir useState()
hook rend les composants fonctionnels plus puissants en leur permettant de posséder un état. Vous pouvez définir une valeur initiale, accéder à la valeur actuelle avec l’assurance qu’elle persistera entre les rendus et mettre à jour l’état à l’aide d’une fonction spécialement fournie.
Les composants fonctionnels avec état sont souvent plus rapides à écrire que leurs homologues basés sur des classes. De plus, ils peuvent rendre plus évident ce qui se passe dans votre base de code en tant que références à state
et setState()
sont éliminés au profit de noms de variables clairs. Finalement, useState()
offre de la flexibilité et signifie que vous n’avez plus besoin de convertir des composants fonctionnels en composants de classe au moment où vous avez besoin d’un état.