Avoir installé nodejs et npm 

NPM

Référence https://practicalprogramming.fr/npm/

Les packages que l'on peut gérer avec npm se trouvent sur le site web https://www.npmjs.com/

Les commandes de base :

// initialiser un package - il faudra ensuite répondre à des questions pour spécifier
npm init -y

// installer un package
npm i nom_du_paquet

// installer un package globalement 
npm i nom_du_paquet -g

// installer des paquets en tant que devDependencies
npm i nom_du_paquet -D

npm vs npx

Si npm est un outil qui permet d'installer des packages, npx est un outil utilisé pour exécuter des packages.

Fonction pure

function sum(a, b) {
  return a + b;
}

Ces fonctions sont dites « pures » parce qu’elles ne tentent pas de modifier leurs entrées et retournent toujours le même résultat pour les mêmes entrées.

En revanche, cette fonction est impure car elle modifie sa propre entrée :

function withdraw(account, amount) {
  account.total -= amount;
}

React applique  une règle stricte :

Tout composant React doit agir comme une fonction pure vis-à-vis de ses props.

JSX et les éléments React

JSX est une surcouche à javascript. Il génère du js via Babel.

Ex :

JSX
jsx
// Cela revient à créer un nouvel élément de React
JS
var element = React.createElement("h1", null, "Hellow world");

Attention

  • quand on crée un élément React, on voit que le premier argument est une balise. Il faut donc choisir une et une seule balise, quitte à :
    • encapsuler d’autres balises dans un unique div par exemple.
    • encapsuler dans un "fragment" en utilisant <React.Fragment> </React.Fragment> ou la syntaxe raccourcie : <></>
  • on remplace "class" par "className"
  • si on veut inclure du javascript, on le fait à l'intérieur des accolades {// js ici}
  • il est recommandé de mettre le jsx entre parenthèses afin d’éviter les pièges d’insertion de point-virgule automatique.

  • Attention, dans le JSX une "balise" de component doit commencer obligatoirement par une majuscule

  • Après la compilation, les expressions JSX deviennent de simples appels de fonctions JavaScript, dont l’évaluation renvoie des objets JavaScript. Ça signifie que vous pouvez utiliser JSX à l’intérieur d’instructions if ou de boucles for, l’affecter à des variables, l’accepter en tant qu’argument, et le renvoyer depuis des fonctions

En savoir plus sur le jsx

Un élément est un objet brut décrivant une instance de composant (de classe en général) ou un nœud DOM et ses propriétés souhaitées. Il contient uniquement des informations sur le type du composant (par exemple, un Button), ses propriétés (par exemple, sa color), et tous ses éléments enfants.

Un élément n’est pas une instance à proprement parler. C’est plutôt un moyen de dire à React ce que vous voulez voir à l’écran. Vous ne pouvez appeler aucune méthode sur l’élément. C’est juste un objet de description immuable avec deux champs :

  • type
  • props

Exemple de code react  représentant un élément : 

Le code HTML suivant :

<button class='button button-blue'>
  <b>
    OK!
  </b>
</button>

... sera représenté par l'élément react suivant (sous forme d’un objet brut) :

{
  type: 'button',
  props: {
    className: 'button button-blue',
    children: {
      type: 'b',
      props: {
        children: 'OK!'
      }
    }
  }
}

 

En savoir plus sur les éléments

Import et export

Depuis ES6, on peut gérer les dépendances entre fichiers avec les mots clés "import" et "export"

Ex

export default class Person {
  constructor(name) {
    this.name = name;
  }
  present() {
    console.log("hello, I'm " + this.name);
  }
}


De cette façon, dans un autre script, on pourra avoir :

import Person from "./Person.js";
const p = new Person("Bob")

Attention, il faudra penser à appeler votre js en utilisant l'attribut type="module"

<script type="module" src="test.10-module.js">

Paramétrage de Visual Studio Code

Installer "vscode-language-babel"

Installer "Theme - Oceanic Next"

Installer “React-Native/React/Redux snippets for es6/es7”

Utiliser les raccourcis clavier suivants :

  • imrc (import react component)
  • ccs (create component class whitout constructor)
  • cccs (create component class with constructor)
  • slr (stateless component with return)

Installer "Auto import - ES6, TS, JSX, TSX"

Comme son nom l'indique, cette extension va automatiquement gérer les imports. ATTENTION à bien installer cette application car d'autres ont presque le même nom et ne fonctionnent pas aussi bien.

Installer "Prettier code formatters"

Aller dans File > Preferences > settings > Text editor > formatting et cocher “Format on save”

Activation de emmet pour les fichier javascript :

Aller dans File > preferences > settings puis cliquer sur l'icône en haut à droite pour ouvrir "settings (UI)"

Ajouter dans le fichier settings.json :

  "emmet.includeLanguages": {
        "javascript": "javascriptreact"
  }

Extension chrome React Developer Tools

Cette extension permet 

  • de voir le hiérarchie React dans Chrome (cf onglet react dans l’inspecteur de chrome)
  • de voir les propriétés states et props dans la fenêtre de droite du même onglet react
  • de chercher des objects react grâce au formulaire de recherche
  • de voir les propriétés d’un objet React grâce à “$r” dans la console après avoir sélectionné l’objet en question dans l’onglet “React”

Arrow function

Vous étiez habitué.e.s à une déclaration de fonction classique du type :

let maFonction = function () {
  //code ici
}

Et bien avec React, c'est (presque) fini !!!

Voici les "arrow functions" ou "fonctions fléchées" :

let maFonction = () => {
//code ici
}

Dans le cas où la fonction attend un seul argument (i dans l'exemple ci-dessous), on peut même écrire :

let maFonction = i => {
//code ici
}

Cela permet d’avoir une syntaxe plus courte que les expressions de fonction classiques.

ATTENTION : la vraie grosse différences avec les fonctions classiques réside dans la valeur de "this" (et oui encore lui -) : 

Dans une "arrow function", this dépend de l'endroit où la fonction est déclarée. Par exemple, si la fonction est déclarée dans une méthode d'objet ou dans un constructeur d'objet, alors "this" sera forcément l'objet en question.

En revanche, dans une fonction classique, on sait que "this" dépend du contexte d'appel de la fonction : si la fonction est appelée depuis une instance d'objet, this devient l'instance en question.

Ex :

class Personne {
        constructor(nom) {
            this.nom = nom;
            this.buttonSePresenter = this.createButtonSePresenter();
        }
        createButtonSePresenter(){
            const button = document.createElement("button");
            button.textContent = "Se présenter";
            document.body.appendChild(button);

            //gestion des événements
            button.onclick = function() {
                console.log(this);//qui est this ?
            }
            return button;
        }
        sePresenter() {
            console.log("Bonjour, je m'appelle " + this.nom);
        }
    }
    const bob = new Personne("Bob");

Dans ce cas précis, quelle sera la valeur de "this" quand l'internaute cliquera sur le bouton "se présenter" ?

Dans ce cas, this sera le bouton lui même puisque la méthode "onclick" est appelée depuis "button"

 

Reprenons cet exemple en utilisant une "arrow function" pour la gestion de l'événement click :

class Personne {
        constructor(nom) {
            this.nom = nom;
            this.buttonSePresenter = this.createButtonSePresenter();
        }
        createButtonSePresenter(){
            const button = document.createElement("button");
            button.textContent = "Se présenter";
            document.body.appendChild(button);

            //gestion des événements
            button.onclick = () => {
                console.log(this);//qui est this ?
            }
            return button;
        }
        sePresenter() {
            console.log("Bonjour, je m'appelle " + this.nom);
        }
    }

const bob = new Personne("Bob");

Dans ce cas, quel sera la valeur de "this" quand l'internaute cliquera sur le bouton "se présenter" ?

This sera égal à l'instance "bob" car onclick a été déclarée dans une méthode de la class Personne.

Bind

La fonction bind(object) crée une nouvelle fonction qui, lorsqu'elle est appelée, a pour contexte this la valeur passée en paramètre.

ATTENTION : Cette méthode est une solution lorsque l'on veut qu'une méhode soit déclarée de façon classique (avec le mot clé function). Par exemple dans le cas de l'utilisation d'une class et que l'on veut que la méthode soit bien stockée dans le prototype du constructeur, il faut utiliser le mot clé function. Le probème récurrent concerne les méthodes gestionnaires d'événement. De façon classique (comme on l'a vu) "this" devient l'objet du dom qui est à la source de l'événement. La solution peut alors consister à "binder" cette méthode dans le constructeur avec une syntaxe du type :

this.handleEventClick = handleEventClick.bind(this);

Méthodes de tableau

map() et littéraux de gabarit

Map est une "Higher-order Functions", c'est à dire qu'elle prendre en paramètre une fonction.

Ellle crée et retourne un nouveau tableau qui transforme tous les éléments du tableau suivant la fonction anonyme (callback) que l'on donnera comme argument de call()

Ex : imaginons que l’on veuille ajouter du code html aux éléments du tableau suivant afin de visualiser une liste à puce.

const fruits = ["Banane", "Pomme", "Kiwi"];
// solution plus classique
const liste_fruits = fruits.map(fruit => "<li>" + fruit + "</li>");
// solution utilisant les littéraux de gabarit
const liste_fruits = fruits.map(fruit => `<li class="fruit"> ${fruit}</li>`);

indexOf()

La méthode indexOf() renvoie le premier indice pour lequel on trouve un élément donné dans un tableau. Si l'élément cherché n'est pas présent dans le tableau, la méthode renverra -1.
Ex : 

let animaux = ['fourmi', 'bison', 'chameau', 'canard'];
console.log(animaux.indexOf('bison'));// résultat attendu : 1

Spread operator (ou …)

L'opérateur spread permet de cloner facilement un objet :

const bob = {
  name: "Bob"
};
const bobbis = { ... bob};
console.log(bobbis);// copie de l'objet bob attendue

L'opérateur spread permet également d'étendre un itérable (par exemple une expression de tableau ou une chaîne de caractères) en lieu et place de plusieurs arguments (pour les appels de fonctions) ou de plusieurs éléments (pour les littéraux de tableaux) ou de paires clés-valeurs (pour les littéraux d'objets).

Condition sans if via une structure de contrôle 

let i = true;
{i && (console.log("hello"))}

 

Opérateur ternaire 

{i ? 'i est vrai' : 'i est faux'}

Objets et tableaux décomposés 

Objet

L'object destructuring existe depuis ECMAScript 6 (2015).

La façon classique de récupérer les propriétés de l'objet p quand p = {nom:"Dylan", prenom:"Bob"} :

const nom = p.nom;
const prenom = p.prenom;

Une syntaxe plus courte existe :

const {nom, prenom} = p;

Si les noms des variables sont déjà utilisés :

const {nom:n, prenom:p} = p;

Tableau

const fruits = ["banane", "cerise"];
const [banane,cerise] = [...fruits];

Littéraux de gabarit ou "template string"

Les littéraux de gabarits sont des littéraux de chaînes de caractères permettant d'intégrer des expressions, c'est-à-dire tout ce qui retourne une valeur.

Le caratère à utiliser s'appelle "Backticks" : ` (altGr + 7)

L'usage de base consiste à imbriquer des variables dans les chaînes, entre ${ et }. Elles se verront "remplacées" par leur valeur au moment de l'exécution.

let nb_kiwis = 3;
const message = `J'ai ${nb_kiwis} kiwis dans mon panier`;
// Résultat : J'ai 3 kiwis dans mon panier

Exemple avec une fonction

function timestamp() { return new Date().getTime() }
const message = `Le timestamp actuel est ${timestamp()}`;