Composant¶
Les types de component¶
Il existe 2 types de composants. Les fonctions (appellées fonctions composants) et les classes.
Une fonction composant est une fonction Javascript qui n’accepte qu’un seul argument appellé props qui signifie « propriétés ». Il peut ne pas y avoir de props. Ce composant doit obligatoirement retourner quelque chose
1 // fonction composant 2 import React from 'react' 3 4 function Welcome(props){ 5 return <h1>Bonjour, {props.name} </h1>; 6 } 7 }
On peut également utiliser une classe ES6 pour définir un composant.
1 // class 2 import React from 'react' 3 4 class Welcome extends React.Component{ 5 render() { 6 return <h1>Bonjour, {this.props.name}</h1>; 7 } 8 } 9 10 // Alternative : import de React.Component à l'aide du destructuring 11 import React, { Component } from 'react' 12 13 class Welcome extends Component { 14 render() { 15 return <h1>Bonjour, {this.props.name}</h1>; 16 } 17 }
Ces 2 composants (la fonction et la classe) sont équivalents.
Une classe doit systématiquement avor une méthode « render(){return(<code JSX/>)} » c’est cette méthode qui modifie le DOM virtuel.
Une fonction doit, systématiquement avoir un « return ».
Choix d’un composant ? Fonction : Classe¶
Depuis la version 16.8.0 de React et l’introduction des hooks, l’utilisation des Fonctions composants est privilégiée par rapport aux Classes.
La philisophie de React est d’avoir des composants le plus simples possible pour pouvoir les réutiliser plus facillement. Les fonctions sont donc à privilégier le plus souvent possible.
Convention de nommage des Composants¶
Pour permettre à JSX d’identifier et d’interpréter les composants que nous créons, ils faut que la première lettre du composant soit en majuscule.
Rendu d’un composant : Comment lier React au DOM ?¶
Pour lier une application au DOM, il faut utiliser le package ReactDOM et la fonction render avec en paramètres, le composant racine de l’application et le noeud du DOM auquel il sera attaché.
1 ReactDOM.render( 2 <MonApplication />, 3 docment.getElementById('root') 4 );
Les éléments peuvent soit représenter un éléments du DOM :
1 const element = <div />;
soit représenter un élément définis par l’utilisateur :
1 const element = <Welcome name="Sara"/>;
Lorsque React rencontre un élément représentant un composant défini par l’utilisateur, il transmet les attributs JSX à ce composant sous la forme d’un objet unique. Nous appelons cet objet « props ».
Le rendu se fait en appellant ReactDOM.render().
1 function Welcome(props){ 2 return <h1>Bonjour, {props.name}</h1>; 3 } 4 5 const element = <Welcome name="Sara"/>; 6 ReactDOM.render( 7 element, 8 document.getElementById('root') 9 );
Détail du déroulement de l’exemple précedent :
On appelle ReactDOM.render() avec l’élément créer par <Welcome name=”Sara”/>.
React appelle le composant Welcome avec comme props {name: “Sara”}.
Notre composant Welcome retourne un élément <h1>Bonjour, Sara</h1> pour résultat.
React DOM met à jour efficacement le DOM pour correspondre à <h1>Bonjour, Sara</h1>.
Parcourrir un tableau et l’afficher sous forme de liste¶
1 {/* JavaScript Object */} 2 var d= {elm1: "Je s'appelle Groot !", 3 elm2: "Je s'appelle Pierre !", 4 eml3: "Je s'appelle atarte"} 5 6 {/* Creation of an array from keys of the "d" object */} 7 var dKeys = Object.keys(d) 8 console.log("dKey : ", dKeys) 9 10 {/* Browsing the "dkeys" array with the map function. The map function use a callback function. 11 Each item (dkey) is given as the unique key ID : ("item", "unique key")=>{...} */} 12 var ul = React.createElement("ul", null, dKeys.map( 13 (dKey, dkey)=>{ 14 return ( 15 React.createElement("li", null, d[dKey]) 16 ) 17 } 18 ) 19 ) 20 console.log(ul) 21 {/* the "ul" function is given to the render */} 22 ReactDOM.render(ul, document.getElementById("app"))
Amélioration sémantique du HTML dans le rendu des composants¶
Les éléments sémantiques sont une des innovations significatives en HTML5. Avant leur apparition, toutes les balises des pages Web étaient créées à l’aide des éléments <div>, auxquels étaient attribués des identificateurs (id) ou des classes (class). Pour placer des panneaux latéraux, des en-têtes, des pieds de page, des éléments de navigation et d’autres blocs de construction, des blocs div avec les valeurs appropriées (par exemple, div = « footer ») ont été utilisés.
HTML5 introduit de nouveaux éléments sémantiques pour la structuration, le regroupement du contenu et le balisage du contenu du texte. Ils décrivent clairement quel contenu ils ont (il y avait <div id = « footer »>, devenu <footer>).
La SEO ainsi que les moteurs de recherches moderne s’appuient en autre sur ces éléments sémantique pour le reférencement des page WEB.
L’utilisation des composant réutilisable dans React à tendence à nous pousser à ne créer que des div, nous privant ainsi d’une partie de la souplesse ammenée avec le HTML5.
Il est interessant de prendre un peu de temps pour permettre aux composant de pouvoir définir dynamiquement c’est balises interne.
1// File: card.js 2import React from "react"; 3 4export function Card(props) { 5 // 1️⃣ Destructure element and children from props 6 const { element, children } = props; 7 8 // 2️⃣ Capitalise element to make it valid jsx 9 let Element = element; 10 11 // 3️⃣ Make "div" the default choice 12 if (!element) { 13 Element = "div"; 14 } 15 16return <Element>{children}</Element>; 17}
L’utilisation se fera alors de la façon suivante :
1// File: exmaple.js 2import React from "react"; 3import { Card } from "./card"; 4 5export function Example() { 6return ( 7 <article> 8 <p>An introduction</p> 9 10 <Card element="aside"> 11 Something related to the article but a little outside of the normal 12 flow. 13 </Card> 14 15 <p>More content...</p> 16 17 <Card element="p">A paragraph with different styling...</Card> 18 19 <p>More content...</p> 20 </article> 21); 22}
Extraire des composants¶
En règle générale, les nouvelles applications React ont un seul composant App à la racine. C’est l’équivalent d’une fonction main(). Pour faciliter la maintenance et la portabilité des éléments, il est conseiller d’avoir un composant App le plus simple possible. Pour cela, on doit isoler, chaque fois que c’est possible, les éléments en composants plus petits (et monotache).
1 function Comment(props) { 2 return ( 3 <div className="Comment"> 4 <div className="UserInfo"> 5 <img className="Avatar" 6 src={props.author.avatarUrl} 7 alt={props.author.name} 8 /> 9 <div className="UserInfo-name"> 10 {props.author.name} 11 </div> 12 </div> 13 <div className="Comment-text"> 14 {props.name} 15 </div> 16 <div className="Comment-date"> 17 {formatDate(props.date)} 18 </div> 19 </div> 20 ); 21 }
Si on définit séparément les composant Avatar et UserInfo, on pourra alors simplifier le composant Comment :
1 // Composant "Avatar" 2 function Avatar(props) { 3 return ( 4 <img className="Avatar" 5 src={props.user.avatarUrl} 6 alt={props.user.name} 7 /> 8 ); 9 } 10 11 // Composant "UserInfo" 12 function UserInfo(props) { 13 return ( 14 <div className="UserInfo"> 15 <Avatar user={props.user} /> 16 <div className="UserInfo-name"> 17 {props.user.name} 18 </div> 19 </div> 20 ); 21 } 22 23 // composant "Comment" 24 function Comment(props) { 25 return ( 26 <div className="Comment"> 27 <UserInfo user={props.author} /> 28 <div className="Comment-text"> 29 {props.text} 30 </div> 31 <div className="Comment-date"> 32 {formatDate(props.date)} 33 </div> 34 </div> 35 ); 36 }
Convertir une fonction en classe¶
Il est possible de convertir une fonction en classe en quelques étapes:
Créez une classe, avec le même nom, qui étend React.Component (ou simplement Component si on l’a importer en destructuring {component}).
Ajoutez-y une méthode vide appelée render().
Déplacez le corps de la fonction dans la méthode render().
Remplacez props par this.props dans le corps de la méthode render(). la méthode render n’a q’un seul élément : “return” suivie d’un bloc JSX entouré de parenthèses.
Supprimez la déclaration désormais vide de la fonction.
1 //Fonction Clock 2 function Clock(props) { 3 return ( 4 <div> 5 <h1>Bonjour, monde !</h1> 6 <h2>Il est {props.date.toLocaleTimeString()}.</h2> 7 </div> 8 ); 9 } 10 11 //Classe Clock après transformation 12 class Clock extends React.Component { 13 render() { 14 return ( 15 <div> 16 <h1>Bonjour, monde !</h1> 17 <h2>Il est {this.props.date.toLocaleTimeString()}.</h2> 18 </div> 19 ); 20 } 21 }