React • Premiers pas
Introduction
Section intitulée « Introduction »Dans cet article, nous allons créer un nouveau projet React à l’aide de Vite.
Nous allons ensuite parcourir chaque fichier afin de comprendre à quoi il sert, comment il fonctionne.
React est une « bibliothèque pour des interfaces utilisateurs web et natives ». Cette bibliothèque permet la « création d’interfaces utilisateurs à l’aide de composants ».
React va nous permettre de découper notre interface utilisateur en blocs individuels. Ces blocs sont appelés « composants ». Un composant peut être :
- une page entière ;
- une portion de page (en-tête de page, pied de page, menu, navigation, section, etc.) ;
- un élément d’UI (un bouton, un lien, une carte, un like, etc.).
Nouveau projet React
Section intitulée « Nouveau projet React »Vite est un outil qui va nous permettre de :
- transpiler/compiler notre code source en fichiers exécutables par un navigateur web ;
- démarrer un serveur web ;
- mettre à jour instantanément la page du navigateur à chaque modification de notre code ;
- et build le projet en fichiers optimisés une fois notre développement terminé.
Suivons le guide proposé par Vite pour créer notre projet React. Plaçons-nous dans le dossier de notre choix et ouvrons un terminal.
npm create vite@latestSuivons les étapes en répondant aux questions :
Ok to proceed? (y)→y;? Project name: »→react-project;? Select a framework: »→React;? Select a variant: »→TypeScript.
Une fois le projet créé, suivons les instructions.
cd react-projectnpm installnpm run devVoici la structure du projet :
RépertoireREACT-PROJECT
Répertoirenode_modules/
- …
Répertoirepublic/
- vite.svg
Répertoiresrc/
Répertoireassets/
- react.svg
- App.css
- App.tsx
- index.css
- main.tsx
- vite-end.d.ts
- .eslintrc.cjs
- .gitignore
- index.html
- package-lock.json
- package.json
- README.md
- tsconfig.app.json
- tsconfig.json
- tsconfig.node.json
- vite.config.ts
Nous allons maintenant parcourir les fichiers et les dossiers de notre projet.
Fichiers de configurations
Section intitulée « Fichiers de configurations »Faisons d’abord le tour des fichiers de configuration de notre projet React.
package.json
Section intitulée « package.json »RépertoireREACT-PROJECT
Répertoirenode_modules/
- …
Répertoirepublic/
- vite.svg
Répertoiresrc/
Répertoireassets/
- react.svg
- App.css
- App.tsx
- index.css
- main.tsx
- vite-end.d.ts
- .eslintrc.cjs
- .gitignore
- index.html
- package-lock.json
- package.json
- README.md
- tsconfig.app.json
- tsconfig.json
- tsconfig.node.json
- vite.config.ts
{ "name": "react-project", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "tsc -b && vite build", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" }, "dependencies": { "react": "^18.3.1", "react-dom": "^18.3.1" }, "devDependencies": { "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^7.13.1", "@typescript-eslint/parser": "^7.13.1", "@vitejs/plugin-react": "^4.3.1", "eslint": "^8.57.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", "typescript": "^5.2.2", "vite": "^5.3.1" }}- name : Nom du projet ;
- private : Un projet privé ne peut être publié sur
npm Registry; - version : Version du projet ;
- scripts : Liste des scripts exécutables via
npm run <script>; - dependencies : Liste des dépendances nécessaires et livrées lors de la phase de build ;
- devDependencies : Liste des dépendances utilisées en phase de développement, mais non livrées lors du build.
dependencies
Section intitulée « dependencies »La section dependencies liste deux dépendances :
react et
react-dom.
La dépendance react contient les fonctionnalités nécessaires pour créer des composants React.
Elle doit être associée à un moteur de rendu :
- react-dom pour le web ;
- react-native pour les applications mobiles iOS et Android.
devDependencies
Section intitulée « devDependencies »Les dépendances listées sous la section devDependencies peuvent être regroupées en plusieurs catégories :
- la librairie TypeScript :
typescript; - les définitions de types pour Typescript :
@types/react,@types/react-dom; - la librairie Vite et ses plugins :
vite,@vitejs/plugin-react; - le linter ESLint et ses plugins :
eslint,eslint-plugin-react-hooks,@typescript-eslint/eslint-plugin, etc.
.eslintrc.cjs
Section intitulée « .eslintrc.cjs »RépertoireREACT-PROJECT
Répertoirenode_modules/
- …
Répertoirepublic/
- vite.svg
Répertoiresrc/
Répertoireassets/
- react.svg
- App.css
- App.tsx
- index.css
- main.tsx
- vite-end.d.ts
- .eslintrc.cjs
- .gitignore
- index.html
- package-lock.json
- package.json
- README.md
- tsconfig.app.json
- tsconfig.json
- tsconfig.node.json
- vite.config.ts
module.exports = { root: true, env: { browser: true, es2020: true }, extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:react-hooks/recommended', ], ignorePatterns: ['dist', '.eslintrc.cjs'], parser: '@typescript-eslint/parser', plugins: ['react-refresh'], rules: { 'react-refresh/only-export-components': [ 'warn', { allowConstantExport: true }, ], },}Ce fichier permet de paramétrer le linter ESLint.
tsconfig.json
Section intitulée « tsconfig.json »RépertoireREACT-PROJECT
Répertoirenode_modules/
- …
Répertoirepublic/
- vite.svg
Répertoiresrc/
Répertoireassets/
- react.svg
- App.css
- App.tsx
- index.css
- main.tsx
- vite-end.d.ts
- .eslintrc.cjs
- .gitignore
- index.html
- package-lock.json
- package.json
- README.md
- tsconfig.app.json
- tsconfig.json
- tsconfig.node.json
- vite.config.ts
{ "compilerOptions": { "composite": true, "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true,
/* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "moduleDetection": "force", "noEmit": true, "jsx": "react-jsx",
/* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"]}La configuration TypeScript est un vaste sujet qui mériterait un article à part entière. Voici néanmoins quelques paramètres à retenir :
- lib : les définitions de types et leurs versions (
DOM,DOM.Iterable,ScriptHost,WebWorker,ES2015,ES2016,ES2017, etc. ) ; - module : la version d’ECMAScript utilisée en phase de développement (
ESNext= version la plus récente) ; - target : la version cible d’ECMAScript lors de la phase de build ;
- strict : active une série d’options de vérifications de type afin d’améliorer la fiabilité et la qualité du code ;
- noUnusedLocals, noUnusedParameters, noFallthroughCasesInSwitch : paramètres supplémentaires permettant d’améliorer la fiabilité et la qualité du code.
vite.config.ts
Section intitulée « vite.config.ts »RépertoireREACT-PROJECT
Répertoirenode_modules/
- …
Répertoirepublic/
- vite.svg
Répertoiresrc/
Répertoireassets/
- react.svg
- App.css
- App.tsx
- index.css
- main.tsx
- vite-end.d.ts
- .eslintrc.cjs
- .gitignore
- index.html
- package-lock.json
- package.json
- README.md
- tsconfig.app.json
- tsconfig.json
- tsconfig.node.json
- vite.config.ts
import { defineConfig } from 'vite'import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/export default defineConfig({ plugins: [react()],})Ce fichier permet de configurer Vite. Le plugin react est ajouté, permettant à Vite de « parler » le langage react. Ainsi Vite est capable de comprendre react, détecter les erreurs et compiler du code source react en javascript natif.
Fichiers de code
Section intitulée « Fichiers de code »Analysons ensuite les fichiers de code.
index.html
Section intitulée « index.html »RépertoireREACT-PROJECT
Répertoirenode_modules/
- …
Répertoirepublic/
- vite.svg
Répertoiresrc/
Répertoireassets/
- react.svg
- App.css
- App.tsx
- index.css
- main.tsx
- vite-end.d.ts
- .eslintrc.cjs
- .gitignore
- index.html
- package-lock.json
- package.json
- README.md
- tsconfig.app.json
- tsconfig.json
- tsconfig.node.json
- vite.config.ts
<!doctype html><html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vite + React + TS</title> </head> <body> <div id="root"></div> <script type="module" src="/src/main.tsx"></script> </body></html>Ce fichier HTML est le point d’entrée de notre application React.
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> utilise le fichier vite.svg stocké dans le dossier public/.
Le body contient :
- un élément
<div>avec l’identifiantroot; - une balise
<script>ayant pour source le fichiermain.tsx.
main.tsx
Section intitulée « main.tsx »RépertoireREACT-PROJECT
Répertoirenode_modules/
- …
Répertoirepublic/
- vite.svg
Répertoiresrc/
Répertoireassets/
- react.svg
- App.css
- App.tsx
- index.css
- main.tsx
- vite-end.d.ts
- .eslintrc.cjs
- .gitignore
- index.html
- package-lock.json
- package.json
- README.md
- tsconfig.app.json
- tsconfig.json
- tsconfig.node.json
- vite.config.ts
import React from 'react'import ReactDOM from 'react-dom/client'import App from './App.tsx'import './index.css'
ReactDOM.createRoot(document.getElementById('root')!).render( <React.StrictMode> <App /> </React.StrictMode>,)Que se passe-t-il ici ?
document.getElementById('root'): retourne l’élément du DOM avec l’identifiantroot;ReactDOM.createRoot(): permet d’associer un élément du DOM à un composant React ;render(<App />): rends le composant ReactAppdans l’élément du DOM.
<div id="root" /> ↔ <App />
Il est ainsi possible d’associer un élément du DOM à un composant React. Nous pouvons créer plusieurs associations si besoin.
De plus, le fichier index.css est importé.
Cela permet d’appliquer tout le CSS déclaré dans ce fichier à l’ensemble de site.
Arrêtons-nous un moment sur la syntaxe utilisée.
JSX est une extension de syntaxe pour Javascript qui permet
d’écrire du code ressemblant à du HTML à l’intérieur d’un fichier Javascript.
Nous pouvons ainsi utiliser des balises HTML standards et des balises représentant des composants React.
Les attributs de ces balises sont la plupart du temps identiques à deux de la balise HTML, à quelques exceptions :
class→className- événements
onclick→onClick
En général le camelCase est utilisé pour les attributs, à quelques exceptions près.
RépertoireREACT-PROJECT
Répertoirenode_modules/
- …
Répertoirepublic/
- vite.svg
Répertoiresrc/
- …
Répertoireassets/
- react.svg
- App.css
- App.tsx
- index.css
- main.tsx
- vite-end.d.ts
- .eslintrc.cjs
- .gitignore
- index.html
- package-lock.json
- package.json
- README.md
- tsconfig.app.json
- tsconfig.json
- tsconfig.node.json
- vite.config.ts
import { useState } from 'react'import reactLogo from './assets/react.svg'import viteLogo from '/vite.svg'import './App.css'
function App() { const [count, setCount] = useState(0)
return ( <> <div> <a href="https://vitejs.dev" target="_blank"> <img src={viteLogo} className="logo" alt="Vite logo" /> </a> <a href="https://react.dev" target="_blank"> <img src={reactLogo} className="logo react" alt="React logo" /> </a> </div> <h1>Vite + React</h1> <div className="card"> <button onClick={() => setCount((count) => count + 1)}> count is {count} </button> <p> Edit <code>src/App.tsx</code> and save to test HMR </p> </div> <p className="read-the-docs"> Click on the Vite and React logos to learn more </p> </> )}
export default AppVoici enfin un composant React !
Un composant React est une fonction qui retourne un (seul et unique) élément.
Ici l’élément retourné est : <> ... </>.
C’est le raccourci pour Fragment : <Fragment> ... </Fragement>.
Un fragment permet de regrouper plusieurs éléments, sans générer de balise HTML.
Il est utile ici pour respecter la règle énoncée juste avant.
À l’intérieur de ce fragment, nous avons du code ressemblant à du HTML. C’est tout l’intérêt de la syntaxe JSX.
Regardons maintenant le code du bouton : <button onClick={() => setCount((count) => count + 1)}>.
L’événement click du bouton est associé à la fonction : () => setCount((count) => count + 1).
La fonction setCount() est déclarée ici : const [count, setCount] = useState(0).
useState() est une fonction fournie par la librairie React.
Cette fonction est un Hook.
Les Hooks sont des fonctions fournies par React qui apportent des fonctionnalités au sein des composants.
Quel genre de fonctionnalités apportent les Hooks ? React propose les groupes suivants :
- Hooks d’état local (State Hooks) : ces hooks permettent de sauvegarder un état entre deux rendus ;
- Hooks de contexte (Context Hooks) : ces hooks permettent de partager un état entre plusieurs composants ;
- Hooks de Ref (Ref Hooks) : ces hooks permettent de sauvegarder des information sans déclencher un rendu ;
- Hooks d’effets (Effect Hooks) : ces hooks permettent de déclencher un effet de bord avec un système extérieur ;
- Hooks de performance (Performance Hooks) : ces hooks permettent d’optimiser les performance (cache, memoization) ;
- Autres Hooks : autres hooks moins souvent utilisés ;
- Hooks personnalisés: nous pouvons également créer nos propres hooks.
Nous reviendrons en détail sur quelques hooks souvent utilisés.
Hook useState()
Section intitulée « Hook useState() »Le hook useState créé une variable d’état dans notre composant.
const [state, setState] = useState(initialState);Le hook useState() retourne un tableau de deux élements :
- La valeur courante de l’état ;
- Une fonction permettant de mettre à jour l’état.
Pourquoi avons-nous besoin de ce hook ?
Modifions le code afin de remplacer le hook par une variable counter.
import { useState } from 'react'import reactLogo from './assets/react.svg'import viteLogo from '/vite.svg'import './App.css'
function App() { const [count, setCount] = useState(0) let counter = 0
return ( <> <div> <a href="https://vitejs.dev" target="_blank"> <img src={viteLogo} className="logo" alt="Vite logo" /> </a> <a href="https://react.dev" target="_blank"> <img src={reactLogo} className="logo react" alt="React logo" /> </a> </div> <h1>Vite + React</h1> <div className="card"> <button onClick={() => setCount((count) => count + 1)}> <button onClick={() => counter++}> count is {count} </button> <p> Edit <code>src/App.tsx</code> and save to test HMR </p> </div> <p className="read-the-docs"> Click on the Vite and React logos to learn more </p> </> )}
export default AppAprès avoir rafraichi la page dans le navigateur, nous remarquons que le bouton n’incrémente plus le compteur. Pourquoi ?
À chaque rendu d’un composant, React appelle la fonction correspondante.
Et le clic sur le bouton déclenche un nouveau rendu.
La variable counter ainsi déclarée dans la fonction App() a pour valeur 0.
Elle aura toujours cette valeur puisqu’elle est recréée à chaque rendu, donc à chaque clic.
Le hook useState permet de résoudre ce problème en conservant la valeur de l’état entre deux rendus.
Conclusion
Section intitulée « Conclusion »Le projet React de départ proposé par Vite nous a permis de beaucoup apprendre. Nous avons ainsi pu voir ensemble :
- comment paramétrer un projet : dépendances npm, bundler Vite, linter ESLint, configuration TypeScript ;
- comment un composant React est ajouté à une page HTML ;
- comment est construit un composant React.
Mais ce n’est que le début, il reste encore beaucoup de choses à découvrir !