L'état d'un composant - State et Props

Comme nous avons pu le voir, les composants sont comme des fonctions JavaScript. Or, dans l'utilisation d'une fonction, on reçoit généralement au moins un paramètre. C'est le cas pour nos composants React, vous recevez ce que l'on appelle des props. A la fin, nous retournons des éléments React qui décrivent ce qui doit apparaître à l’écran.

J'ai également brièvement parlé en introduction du state d'un composant. Celui-ci va correspondre (comme son nom l'indique), à l'état du composant. Concrètement, que ce soit une props ou un state, les 2 correspondent aux propriétés d'un composant : ce qui vont lui permettre d'avoir des informations sur ce qu'il est. La différence fondamental entre les 2 sont leur provenance :

  • Les props proviennent de l'exterieur du composant

  • Le state est une "propriété", son état local

Comme à chaque fois, nous allons traiter le cas du class component et du functional component. Même si la finalité est la même, le procédé ne l'est pas.

Les props

Comme expliqué ci-dessus, une props est une propriété que l'on passe à un composant. C'est donc une information qui vient de "l'exterieur" du composant, généralement, de son parent direct (mais pas toujours).

Pour rappel, React est un arbre de composant et dans nos exemples, nous allons considérons cette architecture

Nous allons démarrer par un exemple avec des class components. Par simplicité, je vais tout vous présenter dans un seul cadre (donc un seul fichier, c'est possible). Libre à vous de vous organiser comme vous le souhaitez.

Je souhaite afficher 2 tweets avec l'information du pseudo et du message

Comment passer une propriété à un composant ?

Exemple avec un class component

Si l'on reprend l'exemple ci-dessus, on passe une propriété à un composant comme si nous écrivions un attribut HTML à notre élément.

<Tweet pseudo="Thor" />

Ici, je donne au composant Tweet la proriété pseudo avec comme valeur Thor. Vous pouvez passer autant de propriété que vous le souhaitez à un composant. Cela peut-être n'importe quel type de donnée. Pour rappel :

Si l'on revient sur notre composant Tweet, je lui passe donc 2 propriétés : pseudo et message. Pour un composant de class, les propriétés vont se charger dans le this de celle-ci. Intéressons-nous à notre this en faisant un console.log : vous y trouverez les différents éléments de votre class comme son contexte, son state, ses refs mais aussi ses props (ce qui nous intéresse pour le moment)

La propriété props contient bien le pseudo et le message

Vous remarquerez que la notation est un peu lourde. Ecrire en permanence this.props avant de sélectionner sa propriété (sans compter que vous pourriez avoir des objets), c'est long... ! N'hésitez pas à vous servir de la destructuration :

De cette manière, vous sécurisez votre propriété qui ne sera pas modifiable (comme on déstructure dans une const), et c'est important que ce soit le cas!

On vient donc de passer une propriété d'un composant vers un autre. Dans les applications React, c’est par le passage de props que l’information circule, toujours des parents vers les enfants.

Exemple avec un functional component

Comme nous sommes dans le cas d'une fonction, le this ne va pas nous intéresser. Nous recevons les propriétés d'un composant grâce au 1er paramètre de la fonction. Voyons plutôt :

Ou encore :

Plus court, plus rapide, plus lisible et tout fonctionne de la même manière. Dans le 2eme exemple, je déstructure immédiatement la propriété props que nous recevons en 1er paramètre. C'est une pratique courante. Après, libre à vous d'utiliser ce que vous souhaitez, il n'y a pas de solution meilleur qu'une autre.

Le state

Le state d'un composant correspond à son état local. Comme nous venons de le voir, les props correspondent à un état en provenance de l'exterieur, le state est lui lié au composant en tant que tel.

Sur notre exemple du Tweet, nous allons créer un état local pour savoir si vous avez aimé le tweet ou pas. Concrètement, cet exemple a très peu d'intérêt car si vous avez besoin d'un état local pour votre composant, c'est que vous souhaitez avoir une interaction avec celui-ci. Dans l'immédiat, nous ne ferons aucune interaction. Nous le verrons lors du prochain cours.

Exemple avec un class component

Pour déclarer un state à votre class component, il vous faut utiliser la méthode de construction : constructor. Comme l'on surcharge cette méthode, il est important d'appeler votre la class parente (Component) afin de continuer de lui fournir les props avec le mot-clé super. Dès lors, vous pouvez initialiser votre state dans votre this :

Dans cet exemple, je me sers de l'état like pour changer la couleur de fond de mon Tweet :

backgroundColor: like ? 'blue' : 'white' : si j'aime le tweet bleu, sinon blanc.

Bien évidemment, vous n'allez pas modifier votre code pour dire si oui ou non le tweet est aimé ou pas. De plus, c'est généralement une information que vous allez recevoir en provenance d'une API. Nous aurions donc tendance à imaginer que ce soit une props. C'est alors à ce moment qu'il faut faire très attention : Vous ne devez jamais initialiser une props dans un state

En d'autres termes, vous ne devez jamais écrire l'exemple ci-dessous :

En faisant cela, vous allez impacter votre cycle de vie (cours suivant) et vous allez obtenir des bugs dans vos données.

Exemple avec un functional component

Dans un functional component, nous n'avons pas de constructeur et pas de this avec lequel nous allons traiter notre state. Le functional component passe par l'intermédiaire des hooks pour créer un état local.

Le hook (qu'on détaillera plus tard) dont nous avons besoin s'appelle : useState

Le hook useState est une fonction qui vous permet d'interagir avec l'état du composant et son cycle de vie. Elle prend en paramètre ce que vous voulez : l'état que vous voulez définir. En l'occurence, je veux définir l'état "like" de mon composant. Suite à cela, cette fonction renvoie une paire de valeurs : l’état actuel et une fonction pour modifer cet état.

Mais qu'en est-il de cet état ? Comment le modifier et pourquoi est-ce lié au cycle de vie d'un composant ? Direction le cours suivant !