JDM

JavaScript / REACT.js / node.js

Liens_Web:

JavaScript

JavaScript est un language interpréter conçu pour s’éxecuter coté client, c’est à dire directement coté navigateur.

Tout comme avec le CSS, il est possible de placer le code JavaScript directement dans la page HTML ou dans un fichier séparé qui sera ensuite appeller depuis le HTML.

Il était anciennement conseiller de faire l’appelle au fichier JS dans le « head » du fichier puisque c’est dans cette section que son regrouper toutes les meta-données de la page WEB. Cependant le chargement d’un fichier HTML étant séquentiel, il est conseiller de placer les scripts JS en bas de page (juste avant « </html> ») pour ne pas ralentir le chargement des autres éléments.

 1 <!-- JS directely loadded in the HTML page -->
 2 <html>
 3     <head>
 4         <!-- MetaDATA -->
 5     </head>
 6     <body>
 7         <!-- some cool stuff -->
 8     </body>
 9     <script>
10         console.log("Je s'appelle Groot !");
11     </script>
12 </html>
13
14 <!-- JS loadded from a seprated file -->
15 <html>
16     <head>
17         <!-- MetaDATA -->
18     </head>
19     <body>
20         <!-- some cool stuff -->
21     </body>
22     <script type="text/javascript" src="myScript.js"></script>
23 </html>

Liste des commandes de bases

Commentaires

Les commentaires sont les mêmes qu’en C :

1 // Commentaire simple
2
3 /*
4     Commentaires
5     sur plusieurs
6     lignes
7 */

Interaction avec l’utilisateur

  1. affichage d’un message à l’écran

1 alert();
2 //ex:
3 var myVar = "un message super important";
4 alert(myVar);
  1. Entrée utilisateur

1 prompt();
2 //ex:
3 var entreeClavier = prompt("tapez du texte ici : ");
  1. Confirmation conditionnelle

1 confirm();
2 //ex:
3 if (confirm('Voulez-vous exécuter le code JavaScript de cette page ?')) {
4     alert('Le code a bien été exécuté !');
5     }
6 /* un Popup doit s'ouvrir et demander de confirmer ([OK]) ou pas ([Annuler])
7 la valeur retournée est alors un booléin (true ou false) */
  1. Affichage dans la console

1console.log("Je s'appelle Groot !");

Type

  1. Les 3 types de bases

    • number : Ce type contient tous les types numériques ( entier et décimaux)

    • string

    • Boolean

  2. Connaitre le type d’une variable

1 typeof
2 //ex:
3 var myVar = 2;
4 alert(typeof myVar);
  1. Conversion de TYPE

    1. String –> Number

    1 parseInt()
    2 //ex:
    3 var myStr, myNumber;
    4 myStr = "1234";
    5 myNumber = parseInt(myStr);
    
    1. Number –> String

    1 //ex:
    2 var myNumber, myStr;
    3 myNumber = 1234;
    4 myStr = myNumber + '';
    5
    6 //ex: (version simplifiée)
    7 var myVar = 12;
    8 myVar += '';
    9 alert(typeof myVar);
    

Opérateur

  1. Opérateur d’égalité : « == » et « === »

 1 var a = 1;
 2 var b = 1;
 3 var c = "1";
 4
 5 //"=="  --> contenu égale à
 6 console.log(a == b);    // true
 7 console.log(a==c);      // true
 8
 9 //"===" --> contenu et type égale à
10 console.log(a === b);   // true
11 console.log(a===c);     // false
  1. Opérateur ternaire

 1 /* a ? [instruction 1] : [instruction 2]
 2
 3     si a est vrai
 4         [instruction 1]
 5     sinon
 6         [instruction 2]
 7 */
 8 // ex :
 9 var a = 1;
10 var myVar = a ? console.log("'a' est vrai") : console.log("'a' est faux");     // "'a' est vrai"
11
12 var a = 0;
13 var myVar = a ? console.log("'a' est vrai") : console.log("'a' est faux");     // "'a' est faux"

Détails syntaxiques

Concaténer les strings

Il y a 2 méthodes permettant de concaténer les chaines de caractères :

  1. Additionner les strings

1 var str1 = "aa"
2 var str2 = "zz"
3 var str12 = "STR1 : " + str1 + " STR2 : " + str2
4 //"STR1 : aa STR2 : zz"
  1. Modifier les chaines directement

    Pour pouvoir modifier les chaines directement, il remplacer les simples cotes < “ … “ > ou les doubles cotes < » … « > par des accent graves (altGR + 7) < ` … ` >

    1 var str1 = "aa"
    2 var str_GR7 = `str1 : ${str1}`
    

Déclaration des variables

  • Constantes

    Les constantes sont définies avec le préfix « const ».

    1 const var_constante = "cc";
    2 var_constante = "nn"
    3 //TypeError: invalid assignment to const `var_constante`
    
  • var

    « var » permet de définir une variable locale. Si la valeur de cette variable est modifiée en dehors de la portée de sa déclaration, la valeur initale sera modifiée / écrasée.

    1 var nom = "aa";
    2 console.log("Avant le bloc : " + nom);      //nom == "aa"
    3 if (true){
    4     var nom = "zz";
    5     console.log("Dans le bloc : " + nom);   //nom == "zz"
    6 }
    7 console.log("Après le bloc : " + nom);      //nom == "zz"
    
  • let

    « let » permet de définir une variable locale. Si la valeur de cette variable est modifiée en dehors de la portée de sa déclaration, la valeur initiale ne sera pas modifiée.

    1 let nom = "aa";
    2 console.log("Avant le bloc : " + nom);      //nom == "aa"
    3 if (true){
    4     let nom = "zz";
    5     console.log("Dans le bloc : " + nom);   //nom == "zz"
    6 }
    7 console.log("Après le bloc : " + nom);      //nom == "aa"
    

Les objets JSON (Object)

Les objets JSON sont l’équivalent des dictionnaires en python. On peux utiliser toute la syntaxe JSON.

1 { id : "id1" }
Extraire les clés (keys) pour les classé dans un tableau
1 var myObject = {
2     id1 : "id1",
3     id2: "id2"
4     }
5
6 var keyFromObject = Object.keys( myObject )     //keyFromObject === ["id1", "id2"]
Quand utiliser “[]” ou “.” pour accéder à une clef

On utilise “[]” dans le cas d’une itération lorsque le nom du membre n’est pas connue. A l’inverse, on utilise “.” pour un appel direct, lorsque le nom du membre est connu

 1 d={'a':1, 'b':2, 'c':3}             //d     --> Object { a: 1, b: 2, c: 3 }
 2 const d_str = Object.keys(d)        //d_str --> Array(3) [ "a", "b", "c" ]
 3
 4 d_str.forEach(
 5     item =>{
 6         console.log(d[item])
 7     }
 8 )                                   //1
 9                                     //2
10                                     //3
11
12 d.a                                 //1
13 d.b                                 //2
14 d.c                                 //3

Les fonctions

  1. Fonctions simples

 1 // Déclaration
 2 function myFunct(myArg1, myArg2){
 3     // un super code ...
 4 }
 5
 6 // appel
 7 myFunct()
 8
 9 /* Variante */
10 var myFunct(myArg1, myArg2) => {
11     //un super code ...
12     }
13 // Le mot clef "function" est suprimé, alors que la flèche " => " est insérée entre
14 // les parenthèses et les accolades
15
16 //si la fonction n'a pas d'argument
17 var myFunct = () => {
18     //un super code ...
19     }
  1. Fonctions anonymes

1 // déclaration
2 function (myArg){
3     // un super code ...
4 }
  1. Exécution immédiate d’une fonction, sans appel préalable

1 (function (myArg){
2     // super code ...
3 })();
4
5 /* Cette syntaxe permet d'exécuter du code isolé
6 sans appel préalable d'une
7 fonction. La fonction anonyme est exécutée automatiquement (et immédiatement)
8 */

Opérateur < … > (spread)

L’opérateur spread ( … ) permet d’éclater les propriétés d’un objet. Ces propriétés sont alors intégrable par d’autres objet.

exemple : Création dans « personne2 », d’une copie de « personne »

1 var personne = {
2     nom : "aa",
3     prenom : "zz"};
4
5     var ville = "ee";
  1. Sans l’opérateur spread

1 var personne2 = {
2     personne,
3     ville};
4
5
6 personne2;
7 {}
8     personne: Object { nom: "aa", prenom: "zz"}
9     ville: "ee"
  1. Avec l’opérateur spread

1 var personne2 = {
2     ...personne,
3     ville};
4
5 personne2;
6 {}
7     nom: "aa"
8     prenom: "zz"
9     ville: "ee"

Dans le premier cas, on constate que l’objet « personne » est maintenant une propriété de « personne2 ». Dans le second cas, seules les propriétés de « personne » ont été ajoutée à « personne2 ».

Opérateur de comparaison « short-circuit »

Il existe un opérateur de comparaison qui retourne une expression seulement si la condition est vraie, contrairement à l’opérateur ternaire qui retourne une expression dans tous les cas.

Cet opérateur est sous utilise le « ET » logique : &&

 1 let isTrue = true
 2 let someExpression = "isTrue est vrai"
 3
 4 isTrue && someExpression        // --> "isTrue est vrai"
 5
 6 isTrue = false
 7 isTrue && someExpression        // --> flase
 8
 9 //cette syntaxe est équivalente à :
10 if (isTrue){
11     someExpression
12     }

Ça fonctionne parce qu’en JavaScript, true && expression est toujours évalué à expression, et false && expression est toujours évalué à false.

La décomposition (destructuring)

Liens_Web:

L’affectation par décomposition (destructuring en anglais) est une expression JavaScript qui permet d’extraire (unpack en anglais) des données d’un tableau ou d’un objet grâce à une syntaxe dont la forme ressemble à la structure du tableau ou de l’objet.

Ces expression peuvent être utilisée pour l’affectation de valeur à une varriable, décomposer un objet JavaScript (un Dictionnaire) ou de décomposer les propriétés d’un objet. C’est égelement la forme utilisée pour n’importer que certaines classes d’une librairie et ainsi éviter de la chargé complétement.

 1 /* Affectation */
 2 var a, b, rest
 3 //Affectation simple
 4 [a, b] = [1, 2]                     //a===1, b===2
 5
 6 //Afectation avec un 'reste' grace à l'opérateur 'spread'
 7 [a, b, ...rest] = [1, 2, 3, 4, 5]   //a===1, b===2, rest = [3, 4, 5]
 8
 9 /* Décomposer un objet */
10 //Décomposition simple
11 var o = {p: 42, q: true};
12 var {p, q} = o;                     //p===42, q===true
13
14 //Décomposition sans affectation
15 var a, b;
16 ({a, b} = {a:1, b:2});              //Les parenthèses ( ... ) utilisées autour de l'instruction
17                                     //sont nécessaires pour que la partie gauche soit bien
18                                     //interprétée comme un objet littéral et non comme un bloc.
19                                     //Il est également nécessaire d'avoir un point-virgule
20                                     //avant les parenthèses de l'instruction car sinon, ces
21                                     //parenthèses peuvent être interprétées comme un appel
22                                     //de fonction.
23
24 //affectation avec un nom différent
25 var o = {p: 42, q: true};
26 var {p: toto, q: truc} = o;         //toto===42, truc===true
27
28 //Décomposer les propriétés d'objets passés en arguments
29 var user = {
30     id: 42,
31     displayName: "jbiche",
32     fullName: {
33         firstName: "Jean",
34         lastName: "Biche"
35     }
36 };
37
38 function userId({id}) {
39     return id;
40 }
41
42 function whois({displayName: displayName, fullName: {firstName: name}}){
43     console.log(displayName + " est " + name);
44 }
45
46 console.log("userId: " + userId(user)); w// "userId: 42"
47     whois(user); // "jbiche est Jean"
48
49                                     //Cela permet d'accéder directement à id, displayName et
50                                     //firstName depuis l'objet user

Les classes

La Création d’une classe se fait avec le mot clef : class. La création d’une instance se fait avec le mot clef : new.

1 class Personne{
2     //...
3 }
4
5 personne = new Personne();

La définission d’attribut de classe se fait dans une méthode « construtor() ». Cette méthode est appellée automatiquement à la création d’une instance de la classe. C’est l’équivalent de la méthode « __init__() » en Python. La définition d’attribut ou l’appel d’une méthode depuis une autre méthode de la classe doit être précéder de « this ». c’est l’équivalent de « self » en Python.

1 class Personne{
2     constructor(nom, prenom){
3         this.nom = nom;
4         this.prenom = prenom;
5     }
6 }
Héritage de classe

L’héritage d’une classe se fait par lajout du terme « extends » suivie du nom de la calsse mère dans la déclaration de classe. Il faut égallement appeller la méthode « super() » dans la méthode « constructor() » de la classe fille.

 1 class Homme extends Personne{
 2     constructor(nom, prenom){
 3         super(nom, prenom);     //Equivalent de Personne.constructor(nom, prenom)
 4         this.sexe = "H";
 5     }
 6
 7     log(){
 8         console.log(`nom : ${this.nom}, prenom : ${this.prenom}`);
 9     }
10 }
11
12 var personne = new Homme("Bond", "James");
13 personne.log();
super()
Liens_Web:

Le mot-clé super est utilisé afin d’appeler ou d’accéder à des fonctions définies sur l’objet parent.

Lorsqu’il est utilisé dans un constructeur, le mot-clé super est utilisé seul et doit apparaître avant le mot-clé this. Ce mot-clé peut également être utilisé afin d’appeler des fonctions sur un objet parent.

Import / Inclusion de module

Un module représente un fichier qui doit être importer dans un autre fichier. Il est possible, mais déconseiller, de faire import de ces modules directement dans le fichier HTML. Cette approche impose de connaitre à l’avance toutes les dépendances et donc nous oblige à inserer tous les fichiers dans l’ordre. De plus le fichier HTML est alors surchargé ce qui peux le rendre difficile à maintenir.

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5     </head>
 6
 7     <body>
 8     </body>
 9
10     <!-- Inclusion des modules externes -->
11     <script src="./personne.js"></script>
12     <script src="./homme.js"></script>
13     <script>
14         var personne = new Homme("Bond", "James");
15         personne.log();
16     </script></script>>
17 </html>

Pour éviter ces problèmes, il faut créer des modules en choisissant les éléments à exposer à l’Aide du termes « export ». Le ficher deveint un module à ce moment là. Il est possible d’exporter plusieurs éléments en les séparant par des virgules.

 1 //module "personne.js"
 2 class Personne{
 3     constructor(nom, prenom){
 4         this.nom = nom;
 5         this.prenom = prenom;
 6     }
 7     log(){
 8         console.log(`nom : ${this.nom}, prenom : ${this.prenom}`);
 9     }
10 }
11
12 export {Personne};

L’utilisation de ces modules se fait à l’aide de la commande « import […] from […] ».

 1 // Module "Homme"
 2 import {Personne} from "./personne.js";
 3
 4 class Homme extends Personne{
 5     constructor(nom, prenom){
 6         super(nom, prenom);     //Equivalent de Personne.constructor(nom, prenom)
 7         this.sexe = "H";
 8     }
 9
10     log(){
11         super.log();
12         console.log("C'est un homme !");
13     }
14 }
15
16 export {Homme};

IL est conseiller d’importer tous les modules dans un seul fichier.

1 import {Personne} from "./personne";
2 import {Homme} from "./homme";
3
4 var personne = new Personne("Gabin", "Jean");
5 personne.log();
6
7 var personne2 = new Homme("Bond", "James");
8 personne2.log();

On peux ensuite importer Ce fichier dans une balise « script » de type « module » dans le fichier html.

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5     </head>
 6
 7     <body>
 8     </body>
 9
10     <!-- Inclusion des modules externes -->
11     <script type="module" src="./index.js"></Script>
12 </html>

Importer du CSS

Si on importe les fichier JavaScript sans préciser l’extention, c’est l’inverse lorsque l’on doit inserer du CSS.

1 import {Personne} from "./personne"
2 import styles from "./css/monSuperCSS.css"
DOM

Le DOM (Document Object Model) est une API qui réprésente et interagit avec tous types de documents HTML ou XML. Le DOM est un modèle de document chargé dans le navigateur. La représentation du document est un arbre nodal. Chaque nœud représente une partie du document (par exemple, un élément, une chaîne de caractères ou un commentaire).

Le DOM est l’une des API les plus utilisées sur le Web parce-qu’il autorise du code exécuté dans un navigateur à accéder et interagir avec chaque nœud dans le document. Les nœuds peuvent être créés, déplacés et modifiés. Des auditeurs d’évènements (event listeners) peuvent être ajoutés à des nœuds et déclenchés par un évènement donné.

À l’origine, DOM n’était pas standardisé. Il ne l’a été que lorsque les navigateurs ont commencé à implémenter JavaScript. Le DOM qui découle de cette période initiale est parfois appelé DOM 0. À l’heure actuelle, le W3C édicte les spécifications de la norme DOM.

Source : DOM sur MDN web docs [8] Voir aussi : DOM sur Wikipedia [9]

AJAX

Le JavaScript et XML asynchrone (AJAX) est une pratique de programmation qui consiste à construire des pages web plus complexes et plus dynamiques en utilisant une technologie connue sous le nom de XMLHttpRequest.

AJAX vous permet de mettre à jour simplement des parties du DOM d’une page web HTML au lieu de devoir recharger la page entière. AJAX vous permet également de travailler de manière asynchrone, c’est-à-dire que votre code continue à s’exécuter pendant que la partie de votre page web essaie de se recharger (par opposition à la méthode synchrone qui bloque l’exécution de votre code jusqu’à ce que la partie de votre page web ait fini de se recharger).

Avec les sites web interactifs et les standards modernes du web, AJAX est progressivement remplacé par des fonctions dans les cadres JavaScript et l’API standard officielle Fetch API.

Source : AJAX sur MDN web docs [10]

Voir aussi :


JSX

Definission de JSX

Le JSX est l’encapsulation d’un pseudo HTML dans du Javascript. cela permet donc de simplifier l’écriture. C’est ce que l’on appel du « sucre syntaxique ».

On écris le html directement dans le code JavaScript, ce qui nous permet d’y inclure directement des composants React.

 1 //Expression en JSX
 2 const element = (
 3     <h1 className="greeting">
 4         Je s'appel Groot !
 5     </h1>
 6 );
 7
 8 //Expression en REACT
 9 const element = React.createlement(
10     'h1',
11     {className: 'greeting'},
12     'Je s'appelle Groot !'
13 );

Ces deux expressions sont équivlente.

Il est possible d’ajouter des commentaire dans une expression JSX. Les commentaire s’écrivent comme pour le JavaScript mais entourés d’accolades.

1 const element = (
2     <h1>
3         {/* un super commentaire bien pertinent */}
4         Je s'appelle Groot !
5     </h1>
6 );

Interpréter le JSX dans un navigateur

Le JSX n’est pas nativement interpréter par les navigateurs. Pour interpréter le JSX dans le navigateur, il faut le prévoir dans le HTML en ajoutant une la bibliothèque « Babel » au moyen de la balise <src= »… »>. Il faut également inclure l’attribut type= »text/babel » dans la balise script contenant le JSX.

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <!-- CDN React - Development -->
 6         <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
 7         <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
 8
 9         <!-- imort de Babel (Dev uniquement) -->
10         <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
11     </head>
12     <body>
13         <div id="app"></div>
14     </body>
15
16     <!-- Balise 'script' avec l'option 'text/babel -->
17     <script type="text/babel">
18         const element = (
19             <h1>
20                 Je s'appel Groot !
21             </h1>
22         );
23         ReactDOM.render(element, document.getElementById("app"));
24     </script>
25 </html>

Avertissement

L’inclusion de Babel pour interpréter le JSX ralentie le programme. En effet, cela ajoute une étape de traduction supplémentaire au processus.

L’inclusion de Babel est donc a reserver à la phase de Developpement. En phase de production on utilisera d’autres outils tel que Webpack pour créer un package.

Details syntaxique

  • Le mot clef “class” habituellement utilisé dans le html ne peut pas être utilisé en JSX car c’est égallement un mot clef utilisé en Javascript. Dans les expressions JSX, ce mot clef est remplacé par « className ».

  • Les mots clefs composés (séparé par « _ ») utilisés en CSS sont systématiquement remplacé par le formatage en lowerCamelCase

  • JSX (et donc React) considère les composants commençant par des lettres minuscules comme des balises DOM. Par exemple, <div /> représente une balise HTML div, mais <Welcome /> représente un composant, et exige que l’identifiant Welcome existe dans la portée courante.

  • Toutes les balises auto-fermantes doivent être fermées avec « / » avant le « > »

    1 <!-- Balise auto-fermantes en HTML -->
    2 <input type="text">
    3
    4 <!-- Balise auto-fermantes en JSX -->
    5 <input type="text" />
    
  • Le JSX n’accepte de retourner qu’un seule élément parent à la fois

     1 // Code en erreur
     2 import React, { Component } from 'react'
     3
     4 class App extends Component {
     5     render() {
     6         return (
     7             {/* Premier composant parent */}
     8             <div>
     9                 <h1>Je s'appelle Groot !<h1/>
    10             <div/>
    11
    12             {/* Second composant parent (Interdit !) */}
    13             <h2>Je s'appelle Pierre<h2/>
    14         )
    15     }
    16
    17 export default App
    

Pour eviter ce problème, on import « Fragment » depuis React et on entoure le JSX d’une balise « <Fragment></Fragment> »

 1 // Code valide
 2 import React, { Component, Fragment } from 'react'
 3
 4 class App extends Component {
 5     render() {
 6         return (
 7             <Fragment>
 8                 {/* Premier composant parent */}
 9                 <div>
10                     <h1>Je s'appelle Groot !<h1/>
11                 <div/>
12
13                 {/* Second composant parent (Interdit !) */}
14                 <h2>Je s'appelle Pierre<h2/>
15             </Fragment>
16         )
17     }
18
19 export default App

React.js

Liens_Web:

React est une bibliothèque Javascript, utilisée pour créer des composants d’affiche. Dans le modèle MVC, React correspond à la Vue.

Pour créer une application avec React, on va créer des composants (des classes ou des fonctions) qui seront ensuite assemblé pour former l’application finale. Les composant React sont réutilisable.

React utilise un DOM virtuel

Lors de l’utilisation de bibliothèques telles que JQuery nous manipulons directement les éléments HTML de la page, c’est à dire le DOM. React ne manipule pas le DOM directement, mais une copie interne de celui-ci (appellé DOM Virtuel), et produit les modifications d’affichage uniquement lorsque cela s’avère nécessaire.

React Native (une variante de React) permet de créer des application IPhone ou Android.

React affiche sont propre html au travers du JSX.

On s’interdit donc d’écrire du html dans le ficher « .html » à l’éxecption du code minimum et des balises <div> qui accueilleront le html de React.

React est composé de 2 bibliothèques JavaScript à inserer dans la page HTML :

  • React : Correspond à React lui même qui permet de créer des composant d’affichage réutilisable.

  • ReactDOM : Extention permettant d’effectuer le rendu, dans une page HTML, les composants créer avec React.

Attention, les deux bibliothèques sont fournie en version « development » et en version « production ».

Le code minimale d’une page est donc :

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5
 6         <!-- CDN React - Development -->
 7         <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
 8         <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
 9
10         <!-- CDN React - Production -->
11         <!-- <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script> -->
12         <!-- <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script> -->
13     </head>
14
15     <body>
16         <div id="app"></div>
17     </body>
18
19     <script>
20         // code React ICI.
21         // ou inclusion d'un module (Ne pas oublier type="module" dans la balise <script>)
22     </script>
23 </html>

Getting started

Liens_Web:

Create React App est un paquet qui permet de créer l’arborescence et d’installer toutes les dépendances nécéssaires. e paquet doit être installer globallement.

1 npm install -g create-react-app
2
3 # Créer ensuite un nouveau projet
4 npx create-react-app [my-app]       # Attention, les noms des projets doivent être écris en
5                                     # minuscule uniquement.
6 cd [my-app]
7 npm start

Versionning et récupération de projet

Lorsqu’un projet react est créer, il est contient un fichier “.gitignore” qui exclue le dossier « node_modules ».

Le dossiers « node_modules » contient toutes les dépendances de React. Ces dépendances sont listées dans le fichiers « package.json ».

Si le projet est récupérer d’un dépot distant comme Github par exemple il faut alors installer les dépendances du projet.

1 cd [my-app]
2 npm install     #lecture du fichier "package.json" pour identifier les dépendances à installer

Composants (component)

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.

Choix d’un composant ? Fonction : Classe

Le choix du type de composant doit se faire en se posant la question :

Est ce a un état (à conserver ou à modifier) ? On parle de Stateful si la réponse est : NON, on parle de Stateless

  • Une classe est (ou peut l’être) Stateful.

  • Une fonction est toujours Stateless.

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 si le composant est Stateless.

Si le composant est Stateful, il n’y à pas le choix, seule une classe répond à ce critère.

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 :

  1. On appelle ReactDOM.render() avec l’élément créer par <Welcome name=”Sara”/>.

  2. React appelle le composant Welcome avec comme props {name: “Sara”}.

  3. Notre composant Welcome retourne un élément <h1>Bonjour, Sara</h1> pour résultat.

  4. 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"))

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:

  1. Créez une classe, avec le même nom, qui étend React.Component (ou simplement Component si on l’a importer en destructuring {component}).

  2. Ajoutez-y une méthode vide appelée render().

  3. Déplacez le corps de la fonction dans la méthode render().

  4. 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.

  5. 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 }

Les props sont en lecture seule

Une fonction est dite « pure » si elle ne tente pas de modifier ses entrées et retourne toujours le même résultat avec les même entrées.

1 // Une fonction pure (qui ne modifie pas ces propres entrées)
2 function sum(a, b) {
3     return a + b;
4 }
5
6 // Une fonction impure (qui modifie ces propres entrées)
7 function withdraw(account, amout) {
8     account.total -= amount;
9 }

React applique une règle stricte :

« Tout composant React doit agir comme une fonction pure vis-a-vis de ses props ».

Les fonctions composants ne pouvant manipuler que des props, on les utilisent lorsque notre composant ne modifie pas sont état. On parle de Composant Stateless.

Lorsqu’un composant doit modifier son état, on utilise une classe.

 1 const famille = {
 2     membre1: {
 3         nom: 'Pierre,
 4         age: 42,
 5         type: 'humain'
 6     },
 7     membre2: {
 8         nom: 'Tartine'
 9         age: 8,
10         type: 'chat'
11     }
12 }
13
14 class App extends Component {
15     // 'state = { famille }' en version destructuration
16     // 'state = { famille : famille }' en version normal
17     state = { famille }
18     render() {
19         const {titre} = this.props
20         const { famille } = this.state
21         return(
22             <div>
23                 <h1>{titre}</h1>
24                 <Membre nom={famille.membre1.nom} />
25                 <Membre nom={famille.membre2.nom} />
26             </div>
27         )
28     }
29 }

props

Liens_Web:
Props

“Props” est un mot clef spécial en React qui représente les propriétées. Il est utilisé pour transmettre des données (propriétés) d’un composant à un autre.

Les propriétés ne sont transmisent que dans un sens : du composant parent vers le composant enfant. On parle de “uni-directionnal flow”. Les data transmisent par les props sont en lectures seules. Cela signifie que les data ne doivent pas être changées par le composant enfant. Si une données doit changer d’état ou de valeur, il faut utiliser les states.

Utilisation des Props

Il faut se rappeler que les props sont des arguments passés aux composants. On peut résumer l’utilisation des props en 3 étapes:

  1. On définie un attribut et sa valeur (Data) sous la forme d’un Objet JavaScript (Dictionnaire) : {Attribut: Value}.

  2. On passe cet attribue à un composant enfant en utilisant “props”.

  3. On effectue le rendu de la data du props.

States

Liens_Web:
hooks
WIP

Une alternative a setState()

React-Router-DOM

Liens_Web:

React-routeur-dom est un paquet qui permet de rediriger vers une nouvelle url et donc d’afficher un nouveau composant en giraant l’esrpie « monopage » de React.

Avertissement

A chaque changement de composant ce dernier est recharger dans le DOM. Il est donc important de percisté les données avec le localstorage ou une base de donnés. Dans le cas contraite toutes les données seront perdu puisque le composant sera chargé à son état initial.


Node.js

Liens_Web:

Node.js (ou Node) est un runtime pour Javascript. Tout comme JRE est le runtime de JAVA. Il permet à Javascript de s’executer en dehors d’un navigateur par exemple coté serveur.


NPM - Packet manager

Liens_Web:
NPM

npm (Node Package Manager) est le gestionnaire de paquets officiel de Node.js. Il permet de télécharger et d’installer des paquets (encore appelés modules ou librairies) pour pouvoir les utiliser pour un projet ou au contraire de partager des paquets pour que d’autres utilisateurs puissent les utiliser.


Package et framework

middleware

Middleware are function that Express executes in the middle after incomming request and before the output. Middlewares might make changes to the request and response objet.

The “use” function registers a middleware with our Express app. With “app.use(express.json())”, the express.json() let’s us retrieve data from a request via the “body” attribute. Without this middleware, data retrieval would be much more difficult.

Express.JS

Epress est un framework qui permet de simplifier la tache d’écriture du code d’un serveur WEB (Backside). Il nous laisse définir les routes et les actions à effectuer lorsqu’une requette HTTP arrive est qu’elle correspond à l’un des patterns que nous avons défini. les patterns utilisé dans la comparaison avec les requèttes HTTP correspondent à une expression regulière.

Il est également possible de créer des middleware qui pourron être inserer dans le traitement entre la requètes HTTP (en entrée) et la réponse (en sortie). Les opérations de logging et d’authentification sont, par exemple traitées à l’aide de middleware.

Babel

Installer babel en mode dévellopeur :

1 npm install --save-dev @babel/core@7 @babel/cli@7
2 # le "@7" signifie que l'on force l'installation de la version 7 du package.

Babel est capable de plusieurs nombreuse convertion / transformation. Il y a cependant un package différent pour chacunes des taches. Le package permettant de convertir le JSX en en Javascript est : PRESET-REACT.