React 

React : Présentation

React est une librairie javascript qui permet de créer des application web

 

Elle utilise Javascript

Pour utiliser React, nous devons installer les prérequis : nodejs

Cette installation installe 3 outils :

  • NodeJS : Le compilateur javascript
  • NPM : Le gestionnaire de dépendance javascript
  • NPX : L’exécuteur de commande javascript

React : Présentation

Pour s'assurer que tout est bien installé vous pouvez exécuter les commandes suivante dans votre terminal :

# Affiche la version de nodejs
node -v

# Affiche la version de NPM
npm -v

# Affiche la version de NPX
npx -v

React : Présentation

  • Le site officiel de React : Vous y retrouverez la documentation de react, ainsi qu'un tutoriel complet
  • Le site de la MDN : C'est LA référence lorsque l'on parle de javascript. Vous y retrouverez l'intégralité de la documentation du langage de programmation JavaScript.

Quelques Liens Utiles :

React : Présentation

Installation

React

Il éxiste différentes technique d'installation de react. Aujourd'hui l'une des plus performante : c'est vite

 

Pour mettre en place une application, rendez-vous le le dossier de votre choix avec un terminal :

React : Installation

npm create vite@latest <nom-du-dossier> --template react-ts

Vous pouvez maintenant installer et lancer l'application :

# On se rend dans le dossier de l'application
cd <nom-du-dossier>
# Install toutes les librairies nescessaire
npm install
# On démarre l'application
npm run dev

React : Installation

Configuration de VSCode

React

React : VSCode

Il est recommandé avant de commencer un projet react de configurer corréctement VSCode.

 

Pour cela nous avons besoin de l'extension prettier permettant de formatter le code javascript automatiquement !

React : VSCode

1. Téléchargez l'extension et installer la sur votre éditeur

React : VSCode

2. Activez le formatage automatique du code lors de la sauvegarde (Fichier > Préférences > Paramètres) :

React : VSCode

3. Ouvrez un fichier js et ouvrez le panneau de commande VSCode (Ctrl + Maj + P ou Cmd + Maj + P sur mac) et recherchez "format" :

3. Cliquez sur "Mettre en forme le document avec ..."

React : VSCode

4. Choisisez "Configurez le formateur par défaut"

5. Cliquez sur "Prettier"

React : VSCode

6. Ajoutez à la racine du projet un fichier `.prettierrc` avec la configuration suivante :

{
  "arrowParens": "avoid",
  "bracketSameLine": false,
  "bracketSpacing": true,
  "embeddedLanguageFormatting": "auto",
  "htmlWhitespaceSensitivity": "css",
  "insertPragma": false,
  "jsxSingleQuote": false,
  "printWidth": 80,
  "proseWrap": "preserve",
  "quoteProps": "as-needed",
  "requirePragma": false,
  "semi": false,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "all",
  "useTabs": false,
  "vueIndentScriptAndStyle": false
}

React

Structure d'un projet

React : Sructure d'un projet

Contient les dépendances javascript ainsi que la configuration de yarn et npm

 

C'est ici que sont noté toutes les librairies javascript nécessaire pour démarrer une application React

React : Sructure d'un projet

Contient la configuration de prettier, l'outil nous permettant de formater le code javascript automatiquement

React : Sructure d'un projet

Contient le fichier de documentation principal. C'est aussi ce fichier qui s'affichera sur github

React : Sructure d'un projet

Contient les fichiers ignorés par git et github

React : Sructure d'un projet

Contient les fichiers publique accessible sur notre application web.

 

Généralement le HTML, les fonts, des images etc ...

React : Sructure d'un projet

Contient le code source de notre application React.

 

C'est ici que nous passerons la majorité de notre temps

React : Sructure d'un projet

Contient les librairies javascript nécessaire au bon fonctionnement de React

React : Structure d'un projet

Contient l'application distribuée et compilée.

 

Vous pouvez créer ce répertoire avec la commande :

npm run build

React

JSX

React : JSX

import React from 'react'
import { render } from 'react-dom'

// Création d'un élément à afficher
// à l'écran
const element = (
  <div>
    <h1>Bonjour !</h1>
    <p>Content de te voir ici.</p>
  </div>
)

// Affichage de l'élément dans la balise avec
// l'id root
render(element, document.querySelector('#root'))

Le JSX est une syntaxe très proche de HTML utilisé pour afficher des balises à l'écran :

React : JSX

import React from 'react'
import { render } from 'react-dom'

// Création d'un élément à afficher
// à l'écran
const element = (
  <div>
    <h1>Bonjour !</h1>
    <p>Content de te voir ici.</p>
  </div>
)

// Affichage de l'élément dans la balise avec
// l'id root
render(element, document.querySelector('#root'))

Nous commençons par importer React, ceci est obligatoire dès que nous faisons du JSX

React : JSX

import React from 'react'
import { render } from 'react-dom'

// Création d'un élément à afficher
// à l'écran
const element = (
  <div>
    <h1>Bonjour !</h1>
    <p>Content de te voir ici.</p>
  </div>
)

// Affichage de l'élément dans la balise avec
// l'id root
render(element, document.querySelector('#root'))

Ensuite nous importons "render" qui permet d'afficher du JSX à l'écran

React : JSX

import React from 'react'
import { render } from 'react-dom'

// Création d'un élément à afficher
// à l'écran
const element = (
  <div>
    <h1>Bonjour !</h1>
    <p>Content de te voir ici.</p>
  </div>
)

// Affichage de l'élément dans la balise avec
// l'id root
render(element, document.querySelector('#root'))

Nous créons ensuite une variable élément avec du JSX (Noté que la syntax est très similaire à HTML !)

React : JSX

import React from 'react'
import { render } from 'react-dom'

// Création d'un élément à afficher
// à l'écran
const element = (
  <div>
    <h1>Bonjour !</h1>
    <p>Content de te voir ici.</p>
  </div>
)

// Affichage de l'élément dans la balise avec
// l'id root
render(element, document.querySelector('#root'))

Il est important de placer des parenthèses autour de nos balises HTML :

React : JSX

import React from 'react'
import { render } from 'react-dom'

// Création d'un élément à afficher
// à l'écran
const element = (
  <div>
    <h1>Bonjour !</h1>
    <p>Content de te voir ici.</p>
  </div>
)

// Affichage de l'élément dans la balise avec
// l'id root
render(element, document.querySelector('#root'))

Ensuite, nous demandons à notre JSX de s'afficher dans la balise avec l'id #root de notre HTML :

React : JSX

import React from 'react'
import { render } from 'react-dom'

const name = 'John Doe'

const element = (
  <div>
    <h1>Bonjour {name}</h1>
    <p>Content de te voir ici.</p>
  </div>
)

// Affichage de l'élément dans la balise avec
// l'id root
render(element, document.querySelector('#root'))

Il est possible d'afficher des variables en JSX en utilisant des { }

React : JSX

import React from 'react'
import { render } from 'react-dom'

const element = (
  <div className="ma-class">
    <h1>Bonjour !</h1>
    <p>Content de te voir ici.</p>
  </div>
)

// Affichage de l'élément dans la balise avec
// l'id root
render(element, document.querySelector('#root'))

Il est possible aussi de définir des attributs de balise :

 "class" est un mot réservé en javascript, en JSX nous utilisons : "className" !

React : JSX

import React from 'react'
import { render } from 'react-dom'

const id = 'super-div'

const element = (
  <div id={id}>
    <h1>Bonjour !</h1>
    <p>Content de te voir ici.</p>
  </div>
)

// Affichage de l'élément dans la balise avec
// l'id root
render(element, document.querySelector('#root'))

Les variables peuvent aussi être utilisées dans les attributs

React : JSX

import React from 'react'
import { render } from 'react-dom'

const name = 'john'
const age = 24

const element = (
  <div dataPersona={`${name}-${age}`}>
    <h1>Bonjour !</h1>
    <p>Content de te voir ici.</p>
  </div>
)

// Affichage de l'élément dans la balise avec
// l'id root
render(element, document.querySelector('#root'))

Il est aussi possible de composer des attributs complexe grâce à l'interpolation :

React : JSX

import React from 'react'
import { render } from 'react-dom'

const notes = [12, 15, 8, 9]

const element = (
  <div>
    <h1>Vos notes :</h1>
    <ul>
      {notes.map(note => (
        <li>{note} / 20</li>
      ))}
    </ul>
  </div>
)

// Affichage de l'élément dans la balise avec
// l'id root
render(element, document.querySelector('#root'))

On peut aussi boucler et afficher tout les éléments d'un tableaux en utilisant "map" !

React : JSX

import React from 'react'
import { render } from 'react-dom'

const notes = [12, 15, 8, 9]

const element = (
  <div>
    <h1>Vos notes :</h1>
    <ul>
      {notes.map((note, index) => (
        <li key={`note-${index}`}>{note} / 20</li>
      ))}
    </ul>
  </div>
)

// Affichage de l'élément dans la balise avec
// l'id root
render(element, document.querySelector('#root'))

Attention pour des raisons de performance il est obligatoire de générer un attribut "key" pour chaque élément JSX d'un tableaux !

React : JSX

// L'élement suivant :
const element = (
  <div>
    <h1>Bonjour</h1>
  </div>
)

// Est compilé comme suivis :
const element = React.createElement('div', {}, [
  React.createElement('h1', {}, 'Bonjour'),
])

Pour bien comprendre JSX, voici comment React traduis le JSX :

React 

Les composant

React : Les composant 

Les composant en React c'est un peu comme des balises HTML personel.

 

En effet, React donne la possibilité de créer nos propres balises HTML : Les Composant

 

Un composant est une simple fonction qui commence par une majuscule et qui retourne du JSX

React : Les composant 

Voici un exemple de composant :

import React from 'react'
import { render } from 'react-dom'

function HelloWorld() {
  return <h1>Bonjour tout le monde !</h1>
}

const element = (
  <div>
    <HelloWorld />
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Nous créons un composant "HelloWorld"

import React from 'react'
import { render } from 'react-dom'

function HelloWorld() {
  return <h1>Bonjour tout le monde !</h1>
}

const element = (
  <div>
    <HelloWorld />
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Nous l'utilisons comme une balise HTML :

import React from 'react'
import { render } from 'react-dom'

function HelloWorld() {
  return <h1>Bonjour tout le monde !</h1>
}

const element = (
  <div>
    <HelloWorld />
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

ATTENTION

Un composant est une fonction qui commence toujours par une majuscule

import React from 'react'
import { render } from 'react-dom'

function HelloWorld() {
  return <h1>Bonjour tout le monde !</h1>
}

const element = (
  <div>
    <HelloWorld />
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Il est aussi possible de spécifier des "attributs" html à nos composants

 

C'est attributs sont nommé les props

 

C'est un objet passé en premier paramètre de notre composant. Cette objet contient tout les attributs ou props de notre composant

React : Les composant 

Voici un éxemple de props :

import React from 'react'
import { render } from 'react-dom'

function Hello(props) {
  return (
    <div>
      <h1>Bonjour {props.name}</h1>
      <p>Vous avez {props.age} ans</p>
    </div>
  )
}

const element = (
  <div>
    <Hello name="John" age={34} />
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Notre composant reçoit un objet "props" contenant les attributs de la balise (ici "name" et "age")

import React from 'react'
import { render } from 'react-dom'

function Hello(props) {
  return (
    <div>
      <h1>Bonjour {props.name}</h1>
      <p>Vous avez {props.age} ans</p>
    </div>
  )
}

const element = (
  <div>
    <Hello name="John" age={34} />
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Nous affichons le contenu des props "name" et "age"

import React from 'react'
import { render } from 'react-dom'

function Hello(props) {
  return (
    <div>
      <h1>Bonjour {props.name}</h1>
      <p>Vous avez {props.age} ans</p>
    </div>
  )
}

const element = (
  <div>
    <Hello name="John" age={34} />
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Lors de l'utilisation du composant, nous passons le "name" et l'age en attribut de notre balise :

import React from 'react'
import { render } from 'react-dom'

function Hello(props) {
  return (
    <div>
      <h1>Bonjour {props.name}</h1>
      <p>Vous avez {props.age} ans</p>
    </div>
  )
}

const element = (
  <div>
    <Hello name="John" age={34} />
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Il est aussi possible de « déstructurer » nos props pour améliorer la lisibilité de nos composants :

import React from 'react'
import { render } from 'react-dom'

function Hello({ name, age }) {
  return (
    <div>
      <h1>Bonjour {name}</h1>
      <p>Vous avez {age} ans</p>
    </div>
  )
}

const element = (
  <div>
    <Hello name="John" age={34} />
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Les composants deviennent ainsi plus simple à lire et a utiliser :

import React from 'react'
import { render } from 'react-dom'

function Hello({ name, age }) {
  return (
    <div>
      <h1>Bonjour {name}</h1>
      <p>Vous avez {age} ans</p>
    </div>
  )
}

const element = (
  <div>
    <Hello name="John" age={34} />
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Il existe une props « spéciale » que l'on appelle les "children"

 

Cette props correspond aux enfants de notre balise :

<div>
  <p>Child 1</p>
  <p>Child 2</p>
</div>

Ici, la balise "div" possède 2 enfants (les balise "p")

React : Les composant 

De la même manière que en HTML, React donne la possibilité de créer ce système :

import React from 'react'
import { render } from 'react-dom'

function BigText({ children }) {
  return (
    <div className="super-big">
      <h1>{children}</h1>
    </div>
  )
}

const element = (
  <div>
    <BigText>Bonjour la compagnie</BigText>
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Tout d'abord, nous déclarons que notre composant accepte des enfants (children) :

import React from 'react'
import { render } from 'react-dom'

function BigText({ children }) {
  return (
    <div className="super-big">
      <h1>{children}</h1>
    </div>
  )
}

const element = (
  <div>
    <BigText>Bonjour la compagnie</BigText>
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Nous affichons les enfants de notre composant "BigText" dans une balise h1

import React from 'react'
import { render } from 'react-dom'

function BigText({ children }) {
  return (
    <div className="super-big">
      <h1>{children}</h1>
    </div>
  )
}

const element = (
  <div>
    <BigText>Bonjour la compagnie</BigText>
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Lors de l'utilisation de notre composant, nous pouvons lui spécifier n'importe quels enfants :

import React from 'react'
import { render } from 'react-dom'

function BigText({ children }) {
  return (
    <div className="super-big">
      <h1>{children}</h1>
    </div>
  )
}

const element = (
  <div>
    <BigText>Bonjour la compagnie</BigText>
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Ou bien :

import React from 'react'
import { render } from 'react-dom'

function BigText({ children }) {
  return (
    <div className="super-big">
      <h1>{children}</h1>
    </div>
  )
}

const element = (
  <div>
    <BigText>
      Bonjour la compagnie
      <br />
      <span>Comment allez-vous ?!</span>
    </BigText>
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Il est aussi possible d'utiliser une solution très puissantes pour rendre nos composants éditable comme des balise HTML

Ce sont les "restProps" qui permettent à un composant d’accepter une infinité de props et de les spécifié à un enfant

Cette technique est utilisé lors du "wrap" de composant. C'est à dire lorsque l'on veut personnaliser une balise HTML déjà existante

React : Les composant 

Un exemple de wrap et de restProps avec une checkox custom :

import React from 'react'
import { render } from 'react-dom'

function MyCheckBox({ size = 'normal', ...restProps }) {
  return (
    <label className={`my-checkbox size-${size}`}>
      <input type="checkbox" {...restProps} />

      {restProps.checked ? <div className="checker"></div> : null}
    </label>
  )
}

const element = (
  <div>
    <MyCheckBox checked={true} id="newsletter"></MyCheckBox>
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Nous ajoutons la props size et récupérons toutes les autres props dans un objet "restProps"

import React from 'react'
import { render } from 'react-dom'

function MyCheckBox({ size = 'normal', ...restProps }) {
  return (
    <label className={`my-checkbox size-${size}`}>
      <input type="checkbox" {...restProps} />

      {restProps.checked ? <div className="checker"></div> : null}
    </label>
  )
}

const element = (
  <div>
    <MyCheckBox checked={true} id="newsletter"></MyCheckBox>
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Nous appliquons toutes les autres props à l'input

import React from 'react'
import { render } from 'react-dom'

function MyCheckBox({ size = 'normal', ...restProps }) {
  return (
    <label className={`my-checkbox size-${size}`}>
      <input type="checkbox" {...restProps} />

      {restProps.checked ? <div className="checker"></div> : null}
    </label>
  )
}

const element = (
  <div>
    <MyCheckBox checked={true} id="newsletter"></MyCheckBox>
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

Ici la props checked et id seront passées à l'input grâce au restProps

import React from 'react'
import { render } from 'react-dom'

function MyCheckBox({ size = 'normal', ...restProps }) {
  return (
    <label className={`my-checkbox size-${size}`}>
      <input type="checkbox" {...restProps} />

      {restProps.checked ? <div className="checker"></div> : null}
    </label>
  )
}

const element = (
  <div>
    <MyCheckBox checked={true} id="newsletter"></MyCheckBox>
  </div>
)

render(element, document.querySelector('#root'))

React : Les composant 

En React chaque composant possède son propre module javascript

 

Ce module doit être nommé à l'identique que le composant qu'il contient

 

Le composant à l'intérieur de ce module lui doit être exporté par défaut

React : Les composant 

Exemple avec le composant Hello

// src/Hello.js
import React from 'react'

export default function Hello({ name }) {
  return (
    <div className="greetings">
      <h1>Hello {name}</h1>
    </div>
  )
}

React : Les composant 

Et maintenant dans l'index.js

// src/index.js
import React from 'react'
import { render } from 'react-dom'
import Hello from './Hello'

render(<Hello />, document.querySelector('#root'))

React : Les composant 

Il existe un composant spécial contenant le cœur de notre application :

Le composant App

// src/App.js
import React from 'react'

export default function App() {
  return (
    <div className="app">
      {/* Ici vient toute l'application */}
    </div>
  )
}

React 

Le Style

React : Le Style

En React il éxiste plusieurs façons de faire du style (css) pour nos composants.

 

La plus simple est l'import d'une feuille de style par composant

 

Il est aussi possible d'utiliser des modules css

 

Ou bien d'installer une librairie comme styled component !

React : Le Style - Import CSS

En react il est tout à fais possible d'importer une feuille de style directement depuis un fichier javascript :

/* src/App.css */
.App {
  background-color: antiquewhite;
  color: darkslategray;
}
import React from 'react'
import './App.css'

export default function App() {
  return (
    <div className="App">
      {/* Ici vient toute l'application */}
    </div>
  )
}

React : Le Style - Import CSS

Création de la feuille de style et import de cette dernière dans la fichier javascript :)

/* src/App.css */
.App {
  background-color: antiquewhite;
  color: darkslategray;
}
import React from 'react'
import './App.css'

export default function App() {
  return (
    <div className="App">
      {/* Ici vient toute l'application */}
    </div>
  )
}

React : Le Style - Import CSS

Cette technique CSS suffit pour de petit projet, mais souffre d'un grand défaut

 

Les classes CSS peuvent entrer en « collision »

 

Rien ne garantit que la class css « App » ne soit pas déjà définit dans une autre feuille de style ainsi provoquant un conflit de class !

 

L'import CSS généralement ne suffit pas à la mise en place d'un design complexe

React : Le Style - Module CSS

React ajoute la possibilité d'importer une feuille de style de la même manière qu'un module javascript :

/* src/App.module.css */
.app {
  background-color: antiquewhite;
  color: darkslategray;
}
// src/App.js
import React from 'react'
import style from './App.module.css'

export default function App() {
  return (
    <div className={style.app}>
      {/* Ici vient toute l'application */}
    </div>
  )
}

React : Le Style - Module CSS

On commence par nommé notre feuille de style "*.module.css"

/* src/App.module.css */
.app {
  background-color: antiquewhite;
  color: darkslategray;
}
// src/App.js
import React from 'react'
import style from './App.module.css'

export default function App() {
  return (
    <div className={style.app}>
      {/* Ici vient toute l'application */}
    </div>
  )
}

React : Le Style - Module CSS

Nous ajoutons le css sous forme de class

/* src/App.module.css */
.app {
  background-color: antiquewhite;
  color: darkslategray;
}
// src/App.js
import React from 'react'
import style from './App.module.css'

export default function App() {
  return (
    <div className={style.app}>
      {/* Ici vient toute l'application */}
    </div>
  )
}

React : Le Style - Module CSS

Nous importons le module css comme un module javascript !

/* src/App.module.css */
.app {
  background-color: antiquewhite;
  color: darkslategray;
}
// src/App.js
import React from 'react'
import style from './App.module.css'

export default function App() {
  return (
    <div className={style.app}>
      {/* Ici vient toute l'application */}
    </div>
  )
}

React : Le Style - Module CSS

Nous appliquons la class contenu dans le module css

/* src/App.module.css */
.app {
  background-color: antiquewhite;
  color: darkslategray;
}
// src/App.js
import React from 'react'
import style from './App.module.css'

export default function App() {
  return (
    <div className={style.app}>
      {/* Ici vient toute l'application */}
    </div>
  )
}

React : Le Style - Module CSS

Cette dernière sera généré avec un nom unique évitant ainsi d'éventuel conflit de nommage

/* src/App.module.css */
.app {
  background-color: antiquewhite;
  color: darkslategray;
}
// src/App.js
import React from 'react'
import style from './App.module.css'

export default function App() {
  return (
    <div className={style.app}>
      {/* Ici vient toute l'application */}
    </div>
  )
}

React : Le Style - Module CSS

Il est aussi possible de designer une application en utilisant une librairie plus puissantes comme styled-components ou encore tailwind

React 

Les Events

React : Les Events

En react, tout comme en html, il est possible d'attacher des événements à nos éléments HTML comme :

- Lors du clique

- Lors du survole de la souris

- Lorsque l'on rentre du text

- etc ...

 

Il existe un très grand nombre d'événements supporté par React nous permettant d’exécuter du code lors d'une action spécifique

React : Les Events

Les events en React s'applique directement sur les attributs de la balise concerné, voici un éxemple avec un simple bouton :

import React from 'react'

export default function MyButton() {
  const myClickEvent = () => {
    console.log('Click !')
  }

  return <button onClick={myClickEvent}></button>
}

React : Les Events

Nous appliquons un événement lors du clique sur notre bouton grâce à l'attribut "onClick" :

import React from 'react'

export default function MyButton() {
  const myClickEvent = () => {
    console.log('Click !')
  }

  return <button onClick={myClickEvent}></button>
}

React : Les Events

Nous créons une fonction qui se lancera à chaque clique sur notre bouton

import React from 'react'

export default function MyButton() {
  const myClickEvent = () => {
    console.log('Click !')
  }

  return <button onClick={myClickEvent}></button>
}

React : Les Events

On donne la fonction à l'attribut "onClick" de notre bouton (ainsi à chaque clique sur le bouton notre fonction sera lancé) :

import React from 'react'

export default function MyButton() {
  const myClickEvent = () => {
    console.log('Click !')
  }

  return <button onClick={myClickEvent}></button>
}

React : Les Events

Il éxiste une très grande variété d'événements tel que :

- onClick

- onPress

- onMouseEnter

- onMouseLeave

- etc ...

 

Vous pouvez retrouver une liste de tout ces événements juste ici

React : Les Events

Il est aussi possible d'obtenir des informations sur l'événement en utilisant l'objet "event" passé en premier paramètre de notre fonction event.

 

Cet objet contient des informations divers sur ce qui vient de se produire, nous pouvons y retrouver des informations comme :

- L’élément HTML ayant produit l'événement

- La position de la souris

- Le touche du clavier ayant été pressée 

- etc ...

React : Les Events

Éxemple : Récupérer le contenu d'un input type text lorsque ce dernier change

import React from 'react'

export default function MyInput() {
  const onChange = ev => {
    const inputValue = ev.target.value

    console.log(`L'input contient la valeur : ${inputValue}`)
  }

  return <input type="text" onChange={onChange} />
}

React : Les Events

Éxemple : Récupérer la position de la souris lorsque cette dernière se déplace dans un élément

import React from 'react'

export default function MyGame() {
  const mousePosition = ev => {
    const x = ev.screenX
    const y = ev.screenY

    console.log(`Position de la souris : x(${x}) y(${y})`)
  }

  return <div onMouseMove={mousePosition} />
}

React : Les Events

Éxemple : Traiter et valider les données d'un formulaire

import React from 'react'

export default function MyForm() {
  const onSubmit = ev => {
    console.log('Traitement et validation du formulaire ...')
  }

  return (
    <form onSubmit={onSubmit}>
      <input type="text" name="email" />
      <input type="password" name="password" />
      <button type="submit">Envoyer</button>
    </form>
  )
}

React : Les Events

Example : Il est aussi possible, tout comme en html, de prévenir le comportement par défaut du navigateur

import React from 'react'

export default function MyForm() {
  const onSubmit = ev => {
    ev.preventDefault()
    console.log('Traitement et validation du formulaire ...')
  }

  return (
    <form onSubmit={onSubmit}>
      <input type="text" name="email" />
      <input type="password" name="password" />
      <button type="submit">Envoyer</button>
    </form>
  )
}

React : Les Events

Example : Ainsi que de stopper la propagation de l'événement

import React from 'react'

export default function MyForm() {
  const handleClick = ev => {
    console.log('Arret de la propagation')
    ev.stopPropagation()
  }

  return (
    <div className="one">
      <div className="two">
        <div className="three" onClick={handleClick}></div>
      </div>
    </div>
  )
}

React : Les Events

Grâce aux événements, une application web devient véritablement dynamique !

 

Cependant, notre interface, notre visuel se doit de réagir lors d'événement, par éxemple :

 

Si je clique sur envoyé, alors une barre de chargement doit apparaître

 

etc ...

React 

Le State

React : Le State

Aujourd'hui, toute application moderne se doit d'être dynamique

 

Lorsque l'on fais certaines actions sur l'interface l'on s'attend à ce que l'interface évolue, change, s'adapte à notre action

 

React met à disposition une notion centrale pour gérer ce « dynamisme »

 

Le State

React : Le State

Afin de bien comprendre de quoi nous parlons, prenons l'éxemple d'un lécteur de musique :

Ce lecteur possède des états (state) :

- Il est en pause

- Son volume est d'environ 75%

- Nous avons joué 30 seconds du titre

- etc ....

React : Le State

De la même manière si je clique sur "play", le lecteur change d'état :

- Il est en lécture

- Nous avons joué 35 secondes du titre

- etc ....

React : Le State

Ainsi nous pouvons créer des variables contenant les informations de notre état :

const estEnPause = true
const tempsEcoule = 30
const tempsTotal = 47
const volume = 75

React : Le State

Et lors du clique sur play, nous changeons notre état :

const estEnPause = false
const tempsEcoule = 35
const tempsTotal = 47
const volume = 75

React : Le State

Et bien c'est exactement ce que permet de faire react grâce à l'état !

const estEnPause = false
const tempsEcoule = 35
const tempsTotal = 47
const volume = 75

React : Le State

Voici un exemple d'état simple avec un conteur :

import React, { useState } from 'react'

export default function AppEvent() {
  const [counter, setCounter] = useState(0)

  const onPlus = () => {
    setCounter(counter + 1)
  }

  const onMinus = () => {
    setCounter(counter - 1)
  }

  return (
    <div>
      <button onClick={onMinus}>-</button>
      <p>Conteur : {counter}</p>
      <button onClick={onPlus}>+</button>
    </div>
  )
}

React : Le State

Ici nous importons "useState" permettant de créer ces variables d'états

import React, { useState } from 'react'

export default function AppEvent() {
  const [counter, setCounter] = useState(0)

  const onPlus = () => {
    setCounter(counter + 1)
  }

  const onMinus = () => {
    setCounter(counter - 1)
  }

  return (
    <div>
      <button onClick={onMinus}>-</button>
      <p>Conteur : {counter}</p>
      <button onClick={onPlus}>+</button>
    </div>
  )
}

React : Le State

Création d'une variable "counter" et de la fonction "setCounter" qui permet de modifier la variable :

import React, { useState } from 'react'

export default function AppEvent() {
  const [counter, setCounter] = useState(0)

  const onPlus = () => {
    setCounter(counter + 1)
  }

  const onMinus = () => {
    setCounter(counter - 1)
  }

  return (
    <div>
      <button onClick={onMinus}>-</button>
      <p>Conteur : {counter}</p>
      <button onClick={onPlus}>+</button>
    </div>
  )
}

React : Le State

Gestion des événements avec changement de l'état

import React, { useState } from 'react'

export default function AppEvent() {
  const [counter, setCounter] = useState(0)

  const onPlus = () => {
    setCounter(counter + 1)
  }

  const onMinus = () => {
    setCounter(counter - 1)
  }

  return (
    <div>
      <button onClick={onMinus}>-</button>
      <p>Conteur : {counter}</p>
      <button onClick={onPlus}>+</button>
    </div>
  )
}

React : Le State

Affichage du conteur

import React, { useState } from 'react'

export default function AppEvent() {
  const [counter, setCounter] = useState(0)

  const onPlus = () => {
    setCounter(counter + 1)
  }

  const onMinus = () => {
    setCounter(counter - 1)
  }

  return (
    <div>
      <button onClick={onMinus}>-</button>
      <p>Conteur : {counter}</p>
      <button onClick={onPlus}>+</button>
    </div>
  )
}

React 

Les Effets

React : Les Effets

Les effets en react sont des fonctions s’exécutant à la suite d'un chagement d'état ou lorsque le composant s'affiche

 

Elles permettent de mettre en place tout un panel d'opérations qui ne sont pas visible pour l'utilisateur mais essentiel pour le bon fonctionnement de l'application !

React : Les Effets

Exemple avec un « lecteur de musique »

Lorsque l'on clique sur « play », la musique doit joué et pause elle doit s'arréter

 

Nous avons donc besoin d'une fonction qui démarre et stop la musique lorsque l'état « play » change !

React : Les Effets

Les effets peuvent être utilisés dans tout un panel d'action :

 

- Allez chercher des données sur une api

- Attendre que l'envoie d'un formulaire soit fais

- Recevoir un message ou une notification

- Envoyer les données d'un formulaire

- etc ...

 

Ils sont absolument central à toute application

web !

React : Les Effets

Prenons un cas pratique : un chronomètre

import React, { useEffect, useState } from 'react'

export default function App() {
  return (
    <>
      <button>Demarrer</button>
      <p>
        Temps écoulé : 0 minute(s) et 0 seconde(s)
      </p>
      <button>Arreter</button>
    </>
  )
}

React : Les Effets

Affiche le chrono

import React, { useEffect, useState } from 'react'

export default function App() {
  return (
    <>
      <button>Demarrer</button>
      <p>
        Temps écoulé : 0 minute(s) et 0 seconde(s)
      </p>
      <button>Arreter</button>
    </>
  )
}

React : Les Effets

Démarre le chronomètre

import React, { useEffect, useState } from 'react'

export default function App() {
  return (
    <>
      <button>Demarrer</button>
      <p>
        Temps écoulé : 0 minute(s) et 0 seconde(s)
      </p>
      <button>Arreter</button>
    </>
  )
}

React : Les Effets

Stop le chronomètre

import React, { useEffect, useState } from 'react'

export default function App() {
  return (
    <>
      <button>Demarrer</button>
      <p>
        Temps écoulé : 0 minute(s) et 0 seconde(s)
      </p>
      <button>Arreter</button>
    </>
  )
}

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  const [started, setStarted] = useState(false)
  const [seconds, setSeconds] = useState(0)
  const [minutes, setMinutes] = useState(0)
  
  return (
    <>
      <button>Demarrer</button>
      <p>
        Temps écoulé : {minutes} minute(s) et {seconds} seconde(s)
      </p>
      <button>Arreter</button>
    </>
  )
}

Création des états

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  const [started, setStarted] = useState(false)
  const [seconds, setSeconds] = useState(0)
  const [minutes, setMinutes] = useState(0)
  
  return (
    <>
      <button>Demarrer</button>
      <p>
        Temps écoulé : {minutes} minute(s) et {seconds} seconde(s)
      </p>
      <button>Arreter</button>
    </>
  )
}

Arrête et démarre le chronomètre

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  const [started, setStarted] = useState(false)
  const [seconds, setSeconds] = useState(0)
  const [minutes, setMinutes] = useState(0)
  
  return (
    <>
      <button>Demarrer</button>
      <p>
        Temps écoulé : {minutes} minute(s) et {seconds} seconde(s)
      </p>
      <button>Arreter</button>
    </>
  )
}

Nombre de secondes du chronomètre

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  const [started, setStarted] = useState(false)
  const [seconds, setSeconds] = useState(0)
  const [minutes, setMinutes] = useState(0)
  
  return (
    <>
      <button>Demarrer</button>
      <p>
        Temps écoulé : {minutes} minute(s) et {seconds} seconde(s)
      </p>
      <button>Arreter</button>
    </>
  )
}

Nombre de minutes du chronomètre

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  const [started, setStarted] = useState(false)
  const [seconds, setSeconds] = useState(0)
  const [minutes, setMinutes] = useState(0)
  
  return (
    <>
      <button>Demarrer</button>
      <p>
        Temps écoulé : {minutes} minute(s) et {seconds} seconde(s)
      </p>
      <button>Arreter</button>
    </>
  )
}

Affichage du temps écoulé

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  const [started, setStarted] = useState(false)
  const [seconds, setSeconds] = useState(0)
  const [minutes, setMinutes] = useState(0)
  
  const start = () => setStarted(true)
  const stop = () => setStarted(false)
  
  return (
    <>
      <button onClick={start}>Demarrer</button>
      <p>
        Temps écoulé : {minutes} minute(s) et {seconds} seconde(s)
      </p>
      <button onClick={stop}>Arreter</button>
    </>
  )
}

On attache les « events » lors du clique sur start et stop

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  const [started, setStarted] = useState(false)
  const [seconds, setSeconds] = useState(0)
  const [minutes, setMinutes] = useState(0)
  
  const start = () => setStarted(true)
  const stop = () => setStarted(false)
  
  useEffect(() => {
    console.log('Je me déclenche dès que started change !')
  }, [started])
  
  return (...)
}

Création d'un effet !

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  const [started, setStarted] = useState(false)
  const [seconds, setSeconds] = useState(0)
  const [minutes, setMinutes] = useState(0)
  
  const start = () => setStarted(true)
  const stop = () => setStarted(false)
  
  useEffect(() => {
    console.log('Je me déclenche dès que started change !')
  }, [started])
  
  return (...)
}

On importe useEffect de React

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  const [started, setStarted] = useState(false)
  const [seconds, setSeconds] = useState(0)
  const [minutes, setMinutes] = useState(0)
  
  const start = () => setStarted(true)
  const stop = () => setStarted(false)
  
  useEffect(() => {
    console.log('Je me déclenche dès que started change !')
  }, [started])
  
  return (...)
}

On créé une fonction qui se déclenchera à chaque changement de l'état "started"

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  // ...
  
  useEffect(() => {
    if (!started) {
      return
    }
  }, [started])
  
  return (...)
}

Si started est « faux » on ne fais rien

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  // ...
  
  useEffect(() => {
    if (!started) {
      return
    }
    
    let elapsedSeconds = 0
  }, [started])
  
  return (...)
}

Création d'une variable qui contiendra le nombre de secondes écoulé

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  // ...
  
  useEffect(() => {
    if (!started) {
      return
    }
    
    let elapsedSeconds = 0
    
    let timer = window.setInterval(() => {
      console.log('Je me lance toute les secondes !')
    }, 1000)
  }, [started])
  
  return (...)
}

Création d'un « interval »; une fonction qui se déclenche toutes les secondes !

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  // ...
  
  useEffect(() => {
    if (!started) {
      return
    }
    
    let elapsedSeconds = 0
    
    let timer = window.setInterval(() => {
      elapsedSeconds += 1
    }, 1000)
  }, [started])
  
  return (...)
}

On augmente le nombre de secondes écoulées

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  // ...
  
  useEffect(() => {
    // ...
    
    let elapsedSeconds = 0
    
    let timer = window.setInterval(() => {
      elapsedSeconds += 1
      
      let newMinutes = Math.floor(elapsedSeconds / 60)
      let newSeconds = elapsedSeconds - newMinutes * 60
    }, 1000)
  }, [started])
  
  return (...)
}

On calcule les minutes et les seconds

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  // ...
  
  useEffect(() => {
    // ...
    
    let elapsedSeconds = 0
    
    let timer = window.setInterval(() => {
      elapsedSeconds += 1
      
      let newMinutes = Math.floor(elapsedSeconds / 60)
      let newSeconds = elapsedSeconds - newMinutes * 60
      
      setMinutes(newMinutes)
      setSeconds(newSeconds)
    }, 1000)
  }, [started])
  
  return (...)
}

On change nos variables d'états

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  // ...
  
  useEffect(() => {
    // ...
    
    let elapsedSeconds = 0
    
    let timer = // ...
    
    return () => {
      console.log(`
        Je me déclenche à la fin de l'effet, lorsque
        l'état « started » passe de « true » à « false » !
      `)
    }
  }, [started])
  
  return (...)
}

On retourne une fonction de « nettoyage » (« clean up »)

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  // ...
  
  useEffect(() => {
    // ...
    
    let elapsedSeconds = 0
    
    let timer = // ...
    
    return () => {
      window.clearInterval(timer)
    }
  }, [started])
  
  return (...)
}

On arréte « l'interval », la fonction qui se déclenche toutes les secondes

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  // ...
  
  useEffect(() => {
    // ...
    
    let elapsedSeconds = 0
    
    let timer = // ...
    
    return () => {
      window.clearInterval(timer)
      setSeconds(0)
      setMinutes(0)
    }
  }, [started])
  
  return (...)
}

On met les secondes et les minutes à 0 !

React : Les Effets

import React, { useEffect, useState } from 'react'

export default function App() {
  const [started, setStarted] = useState(false)
  const [seconds, setSeconds] = useState(0)
  const [minutes, setMinutes] = useState(0)

  const start = () => setStarted(true)
  const stop = () => setStarted(false)

  useEffect(() => {
    if (!started) {
      return
    }

    let elapsedSeconds = 0
    let timer = window.setInterval(() => {
      elapsedSeconds += 1
      let newMinutes = Math.floor(elapsedSeconds / 60)
      let newSeconds = elapsedSeconds - newMinutes * 60

      setMinutes(newMinutes)
      setSeconds(newSeconds)
    }, 1000)

    return () => {
      window.clearInterval(timer)
      setSeconds(0)
      setMinutes(0)
    }
  }, [started])

  return (
    <>
      <button onClick={start}>Demarrer</button>
      <p>
        Temps écoulé : {minutes} minute(s) et {seconds} seconde(s)
      </p>
      <button onClick={stop}>Arreter</button>
    </>
  )
}

Le code final !

React

By David Jegat

React

  • 283