I. Introduction▲
Je veux vous faire un retour sur les applications lourdes, et React est l'une de mes technologies préférées, alors j'ai pensé à créer une introduction sur React. Cet article nécessite comme prérequis des connaissances en HTML et JavaScript. Je pense que vous devriez les connaître avant de pouvoir appréhender une bibliothèque comme React.
II. Qu'est-ce que React ?▲
React est une bibliothèque JavaScript construite en 2013 par l'équipe de développement de Facebook pour rendre les interfaces utilisateurs plus modulaires (ou réutilisables) et plus facilement maintenables. Selon le site web de React, il est utilisé pour « Construire des composants encapsulés qui gèrent leurs propres états, puis les assembler pour réaliser des interfaces utilisateurs complexes ». Je vais utiliser beaucoup d'exemples de Facebook tout au long de cet article, puisqu’étant à l'origine du projet React !
Rappelez-vous quand Facebook est passé d'un simple système de « like » à des systèmes plus complexes avec réactions ? Au lieu de simplement pouvoir « liker » les messages, vous pouvez maintenant réagir de différentes façons avec un cœur, un smiley ou encore un « like » sur n'importe quel article. Si ces réactions étaient principalement faites en HTML, ce serait compliqué de transformer et d'adapter les « likes » en réactions.
C'est à ce moment que React intervient. Plutôt qu'utiliser le principe de « separation of concerns » qui impressionne depuis le premier jour les développeurs, nous avons une architecture différente qui améliore la modularité basée sur une structure par composant plutôt que de séparer les différents langages.
Aujourd'hui, nous allons garder les fichiers CSS séparés, mais vous pouvez rendre celui-ci spécifique si vous le voulez.
III. React vs. Vanilla▲
Lorsque nous parlons de Vanilla Javascript, nous parlons généralement d'écrire du JavaScript sans bibliothèques supplémentaires telles que JQuery, React, Angular ou View. Si vous souhaitez en savoir plus sur ces bibliothèques et sur ce qu'est un framework, j'ai un article sur les frameworks Web.
Quelques notes rapides avant de commencer :
- pour rendre ce tutoriel un peu plus concis, certains exemples de code ont « … » qui les précède ou qui les suit, qui indiquent que du code a été omis.
- j'utilise Git diffs à plusieurs endroits pour afficher les lignes de code qui changerons, donc si vous faites un copier-coller, vous devrez supprimer le signe + au début de la ligne ;
- j'ai des CodePens avec les versions complètes des scripts de chaque section, vous pouvez donc les utiliser pour gagner du temps ;
- les concepts plus avancés qui ne sont pas essentiels pour le tutoriel sont décrits dans des blocs de citation. Ce sont pour la plupart des notions que je pense intéressantes.
IV. Installation▲
Si vous créez une application React en production, vous voudrez utiliser un outil de construction comme Webpack, pour empaqueter votre code, car React utilise certains patrons qui ne fonctionneront pas encore par défaut dans le navigateur. Create Ract App est très utile à ces fins, car il effectue la majeure partie de la configuration pour vous.
Pour l'instant, puisque nous voulons déployer et écrire rapidement une application React, nous utiliserons le CDN, qui doit servir uniquement à des fins de développements. Nous utiliserons également le CDN de Babel pour pouvoir utiliser certaines fonctionnalités JavaScript non standards (nous en reparlerons plus tard).
2.
3.
<
script crossorigin src =
"https://unpkg.com/react@16/umd/react.development.js"
>
<
/
script>
<
script crossorigin src =
"https://unpkg.com/react-dom@16/umd/react-dom.development.js"
>
<
/
script>
<
script src =
"https://cdnjs.cloudflare.com/ajax/libs/babel-core/6.1.19/browser.js"
>
<
/
script>
J'ai aussi un template Code Pen que vous pouvez utiliser.
Dans un projet React complet, je découpe mes composants dans différents fichiers, mais encore une fois, pour les besoins de l'apprentissage, nous allons combiner notre code JavaScript dans un fichier unique pour le moment.
V. Les composants▲
Pour ce tutoriel, nous allons construire un widget de statut Facebook, qui est une fonctionnalité de base dans Facebook depuis longtemps.
Pensez au nombre d'endroits où le widget « likes » apparaît sur Facebook. Vous pouvez aimer un statut, un lien sur un article, une vidéo, une photo ou même une page. Chaque fois que Facebook modifie quelque chose dans le widget « like », ils ne veulent pas être obligés de le faire partout dans le code. C'est là que les composants entrent en jeu. Toutes les parties réutilisables d'une page Web sont mises en abstraction dans un composant qui peut être utilisé encore et encore, et nous n'aurons à changer le code qu'à un seul endroit pour le mettre à jour.
Regardons l'image d'un statut Facebook et séparons-en les différents décomposants en différents composants.
Le statut lui-même sera un composant. Il y a de nombreux statuts dans une chronologie Facebook, nous voulons donc pouvoir réutiliser le composant statut.
Dans ce composant, nous aurons des sous-composants ou des composants dans un composant parent. Ils seront également réutilisables. Le composant de bouton « like » pourrait donc être un enfant des composants PhotoStatus et LinkStatus.
Peut-être que nos sous-composants ressembleraient à ça :
Nous pouvons même avoir des sous-composants avec des sous-composants ! Ainsi, le groupe composé des composts « like », commentaire et partager pourrait être son propre composant ActionBar avec des composants pour « liker », commenter et partager.
Il existe de nombreuses façons de compartimenter ces composants et sous-composants en blocs de codes que vous réutiliserez dans les fonctionnalités dans votre application si vous le souhaitez.
VI. Commençons▲
Je voulais commencer ce tutoriel avec un React « Hello World » - c'est la tradition après tout. Nous passerons ensuite à l'exemple de statut un peu plus complexe.
Dans notre fichier HTML, allons ajouter juste un élément, une balise « div » avec un identifiant (id). Par convention, vous devriez normalement avoir un id « root », ce sera la racine de notre application.
<div id
=
"root"
></div>
Si vous écrivez votre code en utilisant le template Code Pen, vous pouvez écrire le javascript directement dans la section js. Si vous utilisez plutôt votre ordinateur, vous devrez ajouter une balise de script avec le type text/jsx, ainsi :
<
script type=
"text/jsx"
></
script>
Regardons maintenant notre code React :
Tout ce que fait « Hello World » est d'afficher comme une balise H1 sur la page. Passons en revue les étapes.
Premièrement, nous utilisons une classe ES6 qui hérite de la React.Component . C'est un patron que nous utiliserons pour la plupart de nos composants React.
Ensuite, nous avons une méthode dans notre classe, et une méthode spéciale appelée render. React cherche la méthode render pour savoir quoi afficher sur la page. Le nom a du sens. Tout ce qui est retourné par cette méthode render sera rendu par ce composant.
Dans ce cas, nous retournons un H1 avec le texte « Hello World » - c'est exactement ce que nous aurions avec un fichier html.
Enfin, nous avons :
ReactDOM.render
(<
HelloWorld />,
document
.getElementById
(
"root"
))
Nous utilisons la fonctionnalité ReactDOM pour lier notre composant React au DOM.
React utilise quelque chose appelé le DOM virtuel, qui est une représentation virtuelle du DOM avec lequel vous devriez normalement interagir dans Vanilla Javascripy ou JQuery. reactDOM.render fait un rendu du DOM virtuel au DOM normal. En coulisse, React fait plusieurs manipulations pour modifier et restituer efficacement le DOM lorsque quelque chose a été mise à jour.
Notre composant, <HelloWorld /> ressemble à une balise HTML. Cette syntaxe fait partie de JSX, qui est une extension du JavaScript. Vous ne pouvez pas l'utiliser nativement dans les navigateurs. Rappelez-vous comment nous utilisons Babel pour notre JavaScript ? Babel va transpiler (ou convertir) notre code JSX en code JavaScript afin que le navigateur puisse le comprendre.
JSX est optionnel dans React actuellement, mais vous verrez qu'il est utilisé dans la grande majorité des cas.
Ensuite, nous utilisons en JavaScript document.getElementById pour récupérer notre élément root que nous avons créé en HTML.
Globalement, avec ReactDOM.render, nous lions notre composant « HelloWorld » à notre balise div, créée dans notre fichier HTML.
VII. Code de démarrage▲
Nous avons maintenant créé un « Hello World », nous pouvons commencer avec notre composant Facebook.
Premièrement, je veux que vous jouiez avec la démo du code pen. Nous travaillerons avec tout au long du tutoriel. N'hésitez pas à regarder le code aussi, mais ne vous inquiétez pas de ne pas le comprendre. C'est à cela que sert le reste du tutoriel.
Commençons par « coder en dur » le HTML du widget :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
<div class
=
"content"
>
<div class
=
"col-6 offset-3"
>
<div class
=
"card"
>
<div class
=
"card-block"
>
<div class
=
"row"
>
<div class
=
"col-2"
>
<img src
=
"https://zen-of-programming.com/react-intro/selfiesquare.jpg"
class
=
"profile-pic"
>
</div>
<div class
=
"col-10 profile-row"
>
<div class
=
"row"
>
<a href
=
"#"
>
The Zen of Programming</a>
</div>
<div class
=
"row"
>
<small class
=
"post-time"
>
10 mins</small>
</div>
</div>
</div>
<p>Hello World!</p>
<div>
<span class
=
"fa-stack fa-sm"
>
<i class
=
"fa fa-circle fa-stack-2x blue-icon"
></i>
<i class
=
"fa fa-thumbs-up fa-stack-1x fa-inverse"
></i>
</span>
</div>
<div>
<hr class
=
"remove-margin"
>
<div>
<button type
=
"button"
class
=
"btn no-outline btn-secondary"
>
<i class
=
"fa fa-thumbs-o-up fa-4 align-middle"
aria-hidden
=
"true"
></i>
<span class
=
"align-middle"
>
Like</span>
</button>
</div>
</div>
</div>
<div class
=
"card-footer text-muted"
>
<textarea class
=
"form-control"
placeholder
=
"Write a comment..."
></textarea>
<small>120 Remaining</small>
</div>
</div>
</div>
</div>
Avec un peu de CSS, nous obtenons :
Ici le code complet de démarrage
Pour les besoins de ce tutoriel, nous allons créer quatre composants : un composant statut qui sera le parent, un composant « like » qui englobera la logique du « like » et le composant Comment qui contiendra la logique de saisie d'un commentaire. Le composant « like » aura aussi un enfant LikeIcon qui apparaîtra ou non lorsque vous aurez cliqué sur le bouton « like ».
VIII. Architecture des composants▲
Allons-y divisons le code HTML que nous avons écrit dans ces composants.
Nous allons commencer avec le squelette d'un composant, et nous utiliserons le render pour nous assurer qu'il fonctionne.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
class Status extends React.Component {
render() {
return (
<div className
=
"col-6 offset-3"
>
<div className
=
"card"
>
<div className
=
"card-block"
>
<div className
=
"row"
>
<div className
=
"col-10 profile-row"
>
<div className
=
"row"
>
<a href
=
"#"
>
The Zen of Programming</a>
</div>
<div class
=
"row"
>
<small className
=
"post-time"
>
10 mins</small>
</div>
</div>
</div>
</div>
<p>Hello world!</p>
<div className
=
"card-footer text-muted"
/>
</div>
</div>
)
}
}
ReactDOM.render(<Status />
, document.getElementById("root"))
Une remarque intéressante à propos du code ci-dessus : nous avons dû remplacer les attributs de « class » par « className ». Class a déjà une signification en JavaScript, c'est utilisé pour les classes ES6. Certains attributs sont nommés différemment dans le JSX et dans le HTML.
Nous pouvons également supprimer le contenu de notre code HTML, en ne laissant qu'un élément avec l'ID root - le parent « content » est juste pour l'apparence.
Voici le code HTML qui va aller dans le composant Statut. Notez qu'une partie du code HTML original n'est pas encore là, il ira dans nos sous-composants à la place.
Créons un deuxième composant, que nous inclurons dans notre composant Statut.
Voici le composant pour notre commentaire. Il n'y a plus qu'à taper notre textarea, et le texte avec le nombre de caractères qu'il nous reste. Notez que les deux sont encapsulés dans une balise div.Cela est dû au fait que React nous oblige à encapsuler tout le contenu d'un composant dans une balise HTML. Si nous n'avions pas le div parent nous aurions retourné une textarea et un drapeau small.
Nous devons donc maintenant inclure ce composant dans notre composant Statut, puisqu'il s'agira de notre sous-composant. Nous pouvons le faire en utilisant la même syntaxe JSX que celle utilisée pour effectuer un render du composant Status !
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
class Status extends React.Component {
render() {
return (
<div className
=
"col-6 offset-3"
>
<div className
=
"card"
>
<div className
=
"card-block"
>
<div className
=
"row"
>
<div className
=
"col-10 profile-row"
>
<div className
=
"row"
>
<a href
=
"#"
>
The Zen of Programming</a>
</div>
<div className
=
"row"
>
<small className
=
"post-time"
>
10 mins</small>
</div>
</div>
</div>
</div>
<div className
=
"card-footer text-muted"
>
+ <Comment />
</div>
</div>
</div>
)
}
}
Bien, nous avons besoin de faire la même chose pour nos « likes » :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
class LikeIcon extends React.Component {
render() {
return (
<div>
<span className
=
"fa-stack fa-sm"
>
<i className
=
"fa fa-circle fa-stack-2x blue-icon"
/>
<i className
=
"fa fa-thumbs-up fa-stack-1x fa-inverse"
/>
</span>
</div>
)
}
}
class Like extends React.Component {
render() {
return (
<div>
{/* Inclut le sous-composant LikeIcon à l'intérieur du composant Like*/}
<LikeIcon />
<hr />
<div>
<button type
=
"button"
>
<i
className
=
"fa fa-thumbs-o-up fa-4 align-middle"
aria-hidden
=
"true"
/>
<span className
=
"align-middle"
>
Like</span>
</button>
</div>
</div>
)
}
}
Puis nous avons besoin de l'inclure dans composant originel Status :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
class Status extends React.Component {
render() {
return (
<div className
=
"col-6 offset-3"
>
<div className
=
"card"
>
<div className
=
"card-block"
>
<div className
=
"row"
>
<div className
=
"col-10 profile-row"
>
<div className
=
"row"
>
<a href
=
"#"
>
The Zen of Programming</a>
</div>
<div className
=
"row"
>
<small className
=
"post-time"
>
10 mins</small>
</div>
</div>
</div>
+ <Like />
</div>
<div className
=
"card-footer text-muted"
>
<Comment />
</div>
</div>
</div>
)
}
}
Très bien, nous avons maintenant une application React avec notre HTML, mais qui ne fait rien pour l'instant. Nous allons y remédier.
Voici le code de cette section dans code pen.
IX. État et Propriétés▲
Nous avons deux types d'interactions que nous voulons implémenter :
- nous voulons que l'icône « like » soit visible uniquement si le bouton « like » a été cliqué ;
- nous voulons que le nombre de caractères restants diminue.
Commençons à travailler là-dessus.
IX-A. Les Propriétés▲
Imaginez que nous voulions que notre widget commentaire permette un nombre différent de lettres à différents endroits. Sur un statut, par exemple, nous voulons qu'un utilisateur soit autorisé à écrire une réponse d'une longueur de 200 lettres. Sur une photo, cependant, nous voulons seulement qu'il soit capable d'écrire une réponse de 100 caractères.
React nous permet de passer des props(abréviation de propriétés) depuis le composant PictureStatus et Status pour spécifier combien de lettres nous voulons autoriser dans notre réponse, plutôt que d'avoir deux composants commentaires différents.
La syntaxe pour les propriétés est la suivante :
Les props ressemblent à des attributs HTML. Si vous passez une chaîne de caractères via des props, vous n'avez pas besoin des accolades, mais tout autre type de données ou variable doit être entre accolades.
Ensuite, à l'intérieur de notre composante, nous pouvons utiliser nos props :
console.log
(
this.
props.
maxLetters)
Ils sont regroupés dans l'attribut props de l'instance pour être accessibles avec this.props.myPropName.
Changeons donc la limite des 140 caractères codés en dur pour être facilement modifiables en dehors du composant.
Tout d'abord, nous allons changer l'endroit où nous instancions le composant Commentaire dans le composant Statut (notez qu'une partie du code est omise) :
Ensuite, nous modifierons la limite de 140 caractères codés en dur dans le composant Commentaire.
IX-B. État▲
Les props que nous passons d'un composant à l'autre ne changeront jamais dans le composant enfant. Ils peuvent changer dans le parent, mais pas dans l'enfant. Mais, la plupart du temps, nous aurons des attributs que nous voudrons changer au cours de la vie d'un composant. Par exemple, nous voulons savoir combien de caractères l'utilisateur a tapés dans la zone de texte, et nous voulons savoir si l'état a été « liké » ou non. Nous allons stocker les attributs que nous voulons changer dans le composant dans son état.
Vous remarquerez beaucoup d'immuabilité avec React. Il est fortement influencé par le paradigme fonctionnel, de sorte que les effets secondaires sont également découragés.
Nous voulons que cet état soit créé chaque fois que nous créons une nouvelle instance d'un composant, donc nous allons utiliser le constructeur de classe ES6 pour le créer. Si vous voulez un rafraîchissement rapide sur les classes ES6, MDN est une très bonne ressource.
L'état va être un objet avec toutes les paires de clés/valeurs que nous voulons inclure. Dans ce cas, nous voulons un CharacterCount contenant le nombre de caractères saisis par l'utilisateur. Nous allons mettre cela à zéro pour l'instant.
Maintenant, soustrayons cela à notre propriété maxLetters, pour que nous sachions combien de caractères il nous reste.
Si vous augmentez le nombre de caractères(CharacterCount), le nombre de caractères restants diminue.
Mais… rien ne se passe quand vous tapez. Nous ne changerons jamais la valeur de CharacterCount. Nous avons besoin d'ajouter un gestionnaire d'événements sur le textarea afin de changer le characterCount lorsque l'utilisateur tape.
IX-C. Le gestionnaire d'événements▲
Lorsque vous avez utilisé JavaScript dans le passé, vous avez probablement écrit des gestionnaires d'événements pour interagir avec les entrées utilisateur. Nous allons faire la même chose avec React, la syntaxe sera juste un peu différente.
Nous allons ajouter un attribut onChange à notre textarea. À l'intérieur, nous placerons une référence à une méthode qui s'exécutera à chaque fois que l'utilisateur tape dans la zone de texte.
<textarea className
=
"form-control"
placeholder
=
"Write a comment..."
onChange
=
{this.handleChange}/>
Maintenant nous devons créer la méthode handleChange :
class Comment extends React.
Component {
constructor
(
) {
super(
)
this.
state =
{
characterCount
:
0
}
}
handleChange
(
event
) {
console.log
(
event
.
target.
value)
}
...
Pour l'instant, nous ne faisons que le logging dans console.log avec la valeur du textarea event
.
target.
value. Cela fonctionnera de la même manière que dans JavaScript sans React (bien que, si vous regardez un peu plus en détail, l'objet event est un peu différent). Si nous regardons cette console, nous affichons ce que nous tapons dans la zone de texte.
Nous devons maintenant mettre à jour l'attribut characterCount en l'état. Dans React, nous ne modifions jamais directement l'état, donc nous ne pouvons pas faire quelque chose comme ceci : this.state.characterCount = event.target.value.length. Nous devons plutôt utiliser la méthode this.setState.
2.
3.
4.
5.
handleChange
(
event
) {
this.setState
({
characterCount
:
event
.
target.
value.
length
}
)
}
Mais vous obtenez une erreur « Uncaught TypeError : this.setState is not a function ». Cette erreur nous dit qu'il faut préserver le contexte de la classe ES6 dans le gestionnaire d'événements. Nous pouvons le faire en le liant à la méthode dans le constructeur. Si vous voulez en savoir plus à ce sujet, voici un bon article.
Bon, nous y sommes presque. Nous avons juste besoin d'ajouter la possibilité d'activer ou désactiver notre « like ».
Nous devons ajouter un constructeur à notre composant Like. Dans ce constructeur, nous devons instancier l'état du composant. La chose qui changera au cours du cycle de vie du composant est de savoir si le statut a été « liké » ou non.
Maintenant nous devons ajouter un gestionnaire d'événement pour changer le statut :
La différence ici est que la fonction callback this.setState reçoit un paramètre previousState. Comme vous pouvez probablement le deviner d'après le nom du paramètre, c'est la valeur de l'état avant que this.setState soit appelé. setState est asynchrone, donc nous ne pouvons pas compter sur l'utilisation de this.state.liked comme paramètre.
Maintenant, il faut :
a) appeler l'événement chaque fois que l'utilisateur clique sur le bouton « like » ;
b) afficher LikeIcon quand la propriété liked est vraie.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
render
(
) {
return (
<
div>
{
/* Utilisez seulement une logique booléenne pour afficher le LikeIcon si liked est true*/
}
+
{
this.
state.
liked &&
<
LikeIcon />}
<
hr />
<
div>
+
<
button
type=
"button"
className=
"btn no-outline btn-secondary"
onClick={
this.
toggleLike}>
<
i
className=
"fa fa-thumbs-o-up fa-4 align-middle"
aria-
hidden
=
"true"
/>
&
nbsp;
<
span className=
"align-middle"
>
Like</
span>
</
button
>
</
div>
</
div>
)
}
Génial, nous avons maintenant notre fonctionnalité en place.
X. Bonus : composants fonctionnels▲
Si vous avez l'impression d'être déjà dépassé, n'hésitez pas à sauter cette partie, mais je voulais faire un « refactor » rapide de plus pour ce projet. Si nous créons des composants qui n'ont pas d'état associé (que nous appelons composants sans état), nous pouvons transformer nos composants en fonctions au lieu de classes ES6.
Dans ce cas, notre LikeIcon pourrait ressembler à ceci :
Nous retournons simplement l'interface utilisateur du composant au lieu d'utiliser la méthode de rendu.
Ici un CodePen qui utilise ce refactoring !
XI. aide-mémoire▲
J'adore les aides mémoire, donc j'en est fait un avec le contenu de cet article.
Vous pouvez aussi le télécharger en pdf.
XII. Prochaines étapes▲
Pour résumer, nous avons parlé de l'architecture des composants, de la syntaxe de base de React et de JSX, des états et propriétés, des gestionnaires d'événements et des composants fonctionnels.
Si vous souhaitez voir tous les CodePens de ce tutoriel, voici une liste.
Si vous voulez essayer d'étendre le code de ce tutoriel, je vous recommande de changer les « likes » en réactions ou de créer un composant photo qui réutilise certains des composants que nous avons créés.
Aussi, voici d'autres ressources intéressantes pour apprendre React.
XIII. Notes de la rédaction de Developpez.com▲
Cet article est une traduction de ce tutoriel : A Complete Beginner's Guide to React. Nous remercions kevin254kl pour la traduction, Christophe pour la relecture technique et Jacques Jean pour la relecture orthographique.