You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/fr/7-bank-project/4-state-management/README.md

799 lines
41 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Construire une application bancaire Partie 4 : Concepts de gestion détat
## ⚡ Ce que vous pouvez faire dans les 5 prochaines minutes
**Parcours de démarrage rapide pour les développeurs occupés**
```mermaid
flowchart LR
A[⚡ 5 minutes] --> B[Diagnostiquer les problèmes d'état]
B --> C[Créer un objet d'état central]
C --> D[Ajouter la fonction updateState]
D --> E[Voir des améliorations immédiates]
```
- **Minute 1** : Tester le problème détat actuel - se connecter, rafraîchir la page, observer la déconnexion
- **Minute 2** : Remplacer `let account = null` par `let state = { account: null }`
- **Minute 3** : Créer une fonction simple `updateState()` pour des mises à jour contrôlées
- **Minute 4** : Mettre à jour une fonction pour utiliser le nouveau modèle
- **Minute 5** : Tester la meilleure prévisibilité et capacité de débogage
**Test de diagnostic rapide** :
```javascript
// Avant : État dispersé
let account = null; // Perdu au rafraîchissement !
// Après : État centralisé
let state = Object.freeze({ account: null }); // Contrôlé et traçable !
```
**Pourquoi cest important** : En 5 minutes, vous allez expérimenter la transformation dune gestion détat chaotique vers des modèles prévisibles et débogables. Cest la base qui rend les applications complexes maintenables.
## 🗺️ Votre parcours dapprentissage vers la maîtrise de la gestion détat
```mermaid
journey
title De l'État Éparpillé à l'Architecture Professionnelle
section Diagnostic des Problèmes
Identifier les problèmes de perte d'état: 3: You
Comprendre les mises à jour éparses: 4: You
Reconnaître les besoins en architecture: 6: You
section Centralisation du Contrôle
Créer un objet d'état unifié: 5: You
Mettre en œuvre des mises à jour contrôlées: 7: You
Ajouter des modèles immuables: 8: You
section Ajout de Persistance
Implémenter localStorage: 6: You
Gérer la sérialisation: 7: You
Créer la continuité de session: 9: You
section Équilibrer la Fraîcheur
Traiter la vétusté des données: 5: You
Construire des systèmes de rafraîchissement: 8: You
Atteindre un équilibre optimal: 9: You
```
**Destination de votre parcours** : À la fin de cette leçon, vous aurez construit un système de gestion détat professionnel qui gère la persistance, la fraîcheur des données et des mises à jour prévisibles - les mêmes modèles utilisés dans des applications en production.
## Quiz pré-conférence
[Quiz pré-conférence](https://ff-quizzes.netlify.app/web/quiz/47)
## Introduction
La gestion détat est comme le système de navigation du vaisseau Voyager quand tout fonctionne bien, on remarque à peine sa présence. Mais quand il y a un problème, cela fait la différence entre atteindre lespace interstellaire ou dériver perdu dans le vide cosmique. En développement web, létat représente tout ce que votre application doit retenir : le statut de connexion de lutilisateur, les données de formulaire, lhistorique de navigation, et les états temporaires de linterface.
À mesure que votre application bancaire a évolué dun simple formulaire de connexion vers une application plus sophistiquée, vous avez probablement rencontré certains défis courants. Actualiser la page provoque une déconnexion inattendue des utilisateurs. Fermer le navigateur fait disparaître tous les progrès. Déboguer un problème vous amène à explorer plusieurs fonctions qui modifient toutes les mêmes données de manières différentes.
Ce ne sont pas des signes de mauvais code ce sont les douleurs normales de croissance qui surviennent quand les applications atteignent un certain seuil de complexité. Chaque développeur fait face à ces défis lorsque ses applications passent de la phase de « preuve de concept » à « prêtes pour la production ».
Dans cette leçon, nous allons implémenter un système centralisé de gestion détat qui transformera votre application bancaire en une application fiable et professionnelle. Vous apprendrez à gérer les flux de données de manière prévisible, à persister correctement les sessions utilisateur, et à créer une expérience utilisateur fluide que requièrent les applications web modernes.
## Prérequis
Avant de plonger dans les concepts de gestion détat, vous devez avoir configuré correctement votre environnement de développement et avoir les bases de votre application bancaire en place. Cette leçon sappuie directement sur les concepts et le code des parties précédentes de cette série.
Assurez-vous davoir les composants suivants prêts avant de continuer :
**Configuration requise :**
- Terminez la [leçon sur la récupération des données](../3-data/README.md) votre application doit charger et afficher les données de compte avec succès
- Installez [Node.js](https://nodejs.org) sur votre système pour exécuter lAPI backend
- Lancez localement le [serveur API](../api/README.md) pour gérer les opérations sur les données de compte
**Tester votre environnement :**
Vérifiez que votre serveur API fonctionne correctement en exécutant cette commande dans un terminal :
```sh
curl http://localhost:5000/api
# -> devrait retourner "Bank API v1.0.0" en résultat
```
**Ce que fait cette commande :**
- **Envoie** une requête GET à votre serveur API local
- **Teste** la connexion et vérifie que le serveur répond
- **Retourne** les informations de version de lAPI si tout fonctionne correctement
## 🧠 Vue densemble de larchitecture de gestion détat
```mermaid
mindmap
root((Gestion d'État))
Problèmes Actuels
Perte de Session
Problèmes de Rafraîchissement de Page
Impact de la Fermeture du Navigateur
Problèmes de Réinitialisation des Variables
Mises à Jour Éparpillées
Multiples Points de Modification
Défis de Débogage
Comportement Imprévisible
Nettoyage Incomplet
Problèmes d'État de Déconnexion
Fuites de Mémoire
Préoccupations de Sécurité
Solutions Centralisées
Objet d'État Unifié
Source Unique de Vérité
Structure Prévisible
Fondation Evolutive
Mises à Jour Contrôlées
Modèles Immuables
Utilisation de Object.freeze
Changements Basés sur des Fonctions
Suivi d'État
Gestion de l'Historique
Visibilité du Débogage
Audit des Modifications
Stratégies de Persistance
Intégration localStorage
Continuité de Session
Sérialisation JSON
Synchronisation Automatique
Fraîcheur des Données
Rafraîchissement Serveur
Gestion des Données Obsolètes
Optimisation de l'Équilibre
Optimisation du Stockage
Données Minimales
Focus sur la Performance
Considérations de Sécurité
```
**Principe fondamental** : La gestion détat professionnelle équilibre prévisibilité, persistance et performance pour créer des expériences utilisateur fiables, capables dévoluer des interactions simples aux workflows complexes dapplication.
---
## Diagnostic des problèmes actuels détat
À la manière de Sherlock Holmes examinant une scène de crime, nous devons comprendre exactement ce qui se passe dans notre implémentation actuelle avant de résoudre le mystère des sessions utilisateur disparues.
Faisons une expérience simple qui révèle les défis sous-jacents de gestion détat :
**🧪 Essayez ce test de diagnostic :**
1. Connectez-vous à votre application bancaire et allez au tableau de bord
2. Rafraîchissez la page du navigateur
3. Observez ce qui arrive à votre statut de connexion
Si vous êtes redirigé vers lécran de connexion, vous avez découvert le problème classique de persistance détat. Ce comportement survient parce que notre implémentation actuelle stocke les données utilisateur dans des variables JavaScript qui se réinitialisent à chaque chargement de page.
**Problèmes de limplémentation actuelle :**
La simple variable `account` de notre [leçon précédente](../3-data/README.md) crée trois problèmes majeurs qui impactent à la fois lexpérience utilisateur et la maintenabilité du code :
| Problème | Cause technique | Impact utilisateur |
|---------|--------|----------------|
| **Perte de session** | Rafraîchissement de page réinitialise les variables JavaScript | Les utilisateurs doivent se réauthentifier fréquemment |
| **Mises à jour dispersées** | Plusieurs fonctions modifient létat directement | Le débogage devient de plus en plus difficile |
| **Nettoyage incomplet** | La déconnexion ne supprime pas toutes les références détat | Risques potentiels de sécurité et confidentialité |
**Le défi architectural :**
Comme la conception compartimentée du Titanic qui semblait robuste jusquà ce que plusieurs compartiments soient simultanément inondés, corriger ces problèmes individuellement ne règle pas le problème architectural sous-jacent. Nous avons besoin dune solution globale de gestion détat.
> 💡 **Quessayons-nous vraiment daccomplir ?**
La [gestion détat](https://fr.wikipedia.org/wiki/Gestion_d%27%C3%A9tat) consiste en fait à résoudre deux énigmes fondamentales :
1. **Où sont mes données ?** : Suivre quelles informations nous avons et doù elles viennent
2. **Tout le monde est-il sur la même longueur donde ?** : Sassurer que ce que voient les utilisateurs correspond à ce qui se passe réellement
**Notre plan daction :**
Au lieu de courir après notre queue, nous allons créer un système de **gestion détat centralisé**. Pensez-y comme avoir une personne vraiment organisée en charge de toutes les choses importantes :
![Schéma montrant les flux de données entre le HTML, les actions utilisateur et létat](../../../../translated_images/fr/data-flow.fa2354e0908fecc8.webp)
```mermaid
flowchart TD
A[Action Utilisateur] --> B[Gestionnaire d'Événement]
B --> C[Fonction updateState]
C --> D{Validation de l'État}
D -->|Valide| E[Créer Nouvel État]
D -->|Invalide| F[Gestion des Erreurs]
E --> G[Object.freeze]
G --> H[Mise à jour de localStorage]
H --> I[Déclencher Mise à Jour UI]
I --> J[L'Utilisateur Voit les Changements]
F --> K[L'Utilisateur Voit l'Erreur]
subgraph "Couche de Gestion d'État"
C
E
G
end
subgraph "Couche de Persistance"
H
L[localStorage]
H -.-> L
end
```
**Comprendre ce flux de données :**
- **Centralise** tout létat de lapplication en un seul endroit
- **Dirige** tous les changements détat via des fonctions contrôlées
- **Assure** que linterface reste synchronisée avec létat actuel
- **Fournit** un modèle clair et prévisible pour la gestion des données
> 💡 **Perspective professionnelle** : Cette leçon se concentre sur les concepts fondamentaux. Pour les applications complexes, des bibliothèques comme [Redux](https://redux.js.org) offrent des fonctionnalités avancées de gestion détat. Comprendre ces principes de base vous aidera à maîtriser nimporte quelle bibliothèque de gestion détat.
> ⚠️ **Sujet avancé** : Nous ne couvrirons pas les mises à jour automatiques de linterface déclenchées par les changements détat, car cela implique des concepts de [programmation réactive](https://fr.wikipedia.org/wiki/Programmation_r%C3%A9active). Considérez cela comme une excellente étape suivante dans votre parcours dapprentissage !
### Tâche : Centraliser la structure détat
Commençons à transformer notre gestion détat dispersée en un système centralisé. Cette première étape établit les bases de toutes les améliorations à venir.
**Étape 1 : Créez un objet détat central**
Remplacez la simple déclaration `account` :
```js
let account = null;
```
Par un objet détat structuré :
```js
let state = {
account: null
};
```
**Pourquoi ce changement est important :**
- **Centralise** toutes les données de lapplication en un seul endroit
- **Prépare** la structure pour ajouter plus de propriétés détat plus tard
- **Établit** une frontière claire entre létat et les autres variables
- **Crée** un modèle qui évolue avec la croissance de votre application
**Étape 2 : Mettez à jour les schémas daccès à létat**
Mettez à jour vos fonctions pour utiliser la nouvelle structure détat :
**Dans les fonctions `register()` et `login()`**, remplacez :
```js
account = ...
```
Par :
```js
state.account = ...
```
**Dans la fonction `updateDashboard()`**, ajoutez cette ligne en haut :
```js
const account = state.account;
```
**Ce que ces mises à jour accomplissent :**
- **Conservent** la fonctionnalité existante tout en améliorant la structure
- **Préparent** votre code à une gestion détat plus sophistiquée
- **Créent** des modèles cohérents pour accéder aux données détat
- **Établissent** la base pour des mises à jour centralisées de létat
> 💡 **Note** : Ce refactoring ne résout pas immédiatement nos problèmes, mais crée la base essentielle pour les puissantes améliorations à venir !
### 🎯 Bilan pédagogique : Principes de centralisation
**Pause et réflexion** : Vous venez dimplémenter la base de la gestion détat centralisée. Cest une décision architecturale cruciale.
**Auto-évaluation rapide** :
- Pouvez-vous expliquer pourquoi centraliser létat dans un objet est préférable à des variables dispersées ?
- Que se passerait-il si vous oubliez de mettre à jour une fonction pour utiliser `state.account` ?
- Comment ce modèle prépare-t-il votre code à des fonctionnalités plus avancées ?
**Lien avec le monde réel** : Le modèle de centralisation que vous avez appris est la base des frameworks modernes comme Redux, Vuex, et React Context. Vous construisez la même pensée architecturale utilisée dans les grandes applications.
**Question de défi** : Si vous deviez ajouter des préférences utilisateur (thème, langue) dans votre application, où les ajouteriez-vous dans la structure détat ? Comment cela évoluerait-il ?
## Implémenter des mises à jour détat contrôlées
Avec notre état centralisé, létape suivante consiste à établir des mécanismes contrôlés pour les modifications de données. Cette approche assure des changements détat prévisibles et un débogage facilité.
Le principe central ressemble au contrôle du trafic aérien : au lieu de permettre à plusieurs fonctions de modifier létat indépendamment, nous allons canaliser tous les changements via une fonction unique et contrôlée. Ce modèle offre une supervision claire de quand et comment les données changent.
**Gestion détat immuable :**
Nous traiterons notre objet `state` comme [*immuable*](https://fr.wikipedia.org/wiki/Objet_immuable), ce qui signifie que nous ne le modifions jamais directement. À chaque changement, nous créons un nouvel objet détat avec les données mises à jour.
Bien que cette approche puisse sembler inefficace au premier abord comparée aux modifications directes, elle offre dimportants avantages pour le débogage, les tests et la prévisibilité de lapplication.
**Avantages de la gestion détat immuable :**
| Avantage | Description | Impact |
|---------|-------------|--------|
| **Prévisibilité** | Les changements ne se font que via des fonctions contrôlées | Plus facile à déboguer et tester |
| **Suivi historique** | Chaque changement détat crée un nouvel objet | Permet la fonctionnalité dannulation/restauration |
| **Prévention des effets de bord** | Pas de modifications accidentelles | Évite les bugs mystérieux |
| **Optimisation des performances** | Facile à détecter quand létat a réellement changé | Permet des mises à jour UI efficaces |
**Immutabilité en JavaScript avec `Object.freeze()` :**
JavaScript fournit [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) pour empêcher les modifications dobjet :
```js
const immutableState = Object.freeze({ account: userData });
// Toute tentative de modifier immutableState générera une erreur
```
**Décryptage de ce qui se passe ici :**
- **Empêche** les affectations ou suppressions directes de propriétés
- **Lance** des exceptions si des tentatives de modification sont faites
- **Garantit** que les changements détat doivent se faire via des fonctions contrôlées
- **Crée** un contrat clair sur la manière de mettre à jour létat
> 💡 **Approfondissement** : Apprenez la différence entre objets immuables *superficiels* et *profonds* dans la [documentation MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze). Comprendre cette distinction est crucial pour des structures détat complexes.
```mermaid
stateDiagram-v2
[*] --> StateV1: État Initial
StateV1 --> StateV2: updateState('account', newData)
StateV2 --> StateV3: updateState('account', anotherUpdate)
StateV3 --> StateV4: updateState('preferences', userSettings)
note right of StateV1
Object.freeze()
Immutable
Déboguable
end note
note right of StateV2
Nouvel objet créé
État précédent préservé
Changements prévisibles
end note
```
### Tâche
Créons une nouvelle fonction `updateState()` :
```js
function updateState(property, newData) {
state = Object.freeze({
...state,
[property]: newData
});
}
```
Dans cette fonction, nous créons un nouvel objet détat et copions les données de létat précédent en utilisant l[*opérateur spread (`...`)*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Ensuite, nous écrasons une propriété particulière de lobjet détat avec les nouvelles données en utilisant la [notation entre crochets](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` pour lassignation. Enfin, nous bloquons lobjet pour empêcher les modifications avec `Object.freeze()`. Pour linstant, nous avons uniquement la propriété `account` stockée dans létat, mais avec cette approche, vous pouvez ajouter autant de propriétés que nécessaire.
Nous allons aussi mettre à jour linitialisation de `state` pour sassurer que létat initial est gelé aussi :
```js
let state = Object.freeze({
account: null
});
```
Ensuite, mettez à jour la fonction `register` en remplaçant lassignation `state.account = result;` par :
```js
updateState('account', result);
```
Faites de même avec la fonction `login`, en remplaçant `state.account = data;` par :
```js
updateState('account', data);
```
Profitons-en également pour régler le problème des données de compte non effacées lorsque lutilisateur clique sur *Déconnexion*.
Créez une nouvelle fonction `logout()` :
```js
function logout() {
updateState('account', null);
navigate('/login');
}
```
Dans `updateDashboard()`, remplacez la redirection `return navigate('/login');` par `return logout()`;
Essayez de créer un nouveau compte, de vous déconnecter puis de vous reconnecter pour vérifier que tout fonctionne correctement.
> Conseil : vous pouvez regarder tous les changements détat en ajoutant `console.log(state)` au bas de `updateState()` et en ouvrant la console des outils de développement de votre navigateur.
## Implémenter la persistance des données
Le problème de perte de session que nous avons identifié plus tôt nécessite une solution de persistance qui maintient létat utilisateur à travers les sessions du navigateur. Cela transforme notre application dune expérience temporaire en un outil fiable et professionnel.
Considérez comment les horloges atomiques maintiennent une précision temporelle même lors de coupures de courant en stockant létat critique dans une mémoire non volatile. De même, les applications web ont besoin de mécanismes de stockage persistants pour préserver les données essentielles de lutilisateur à travers les sessions et rafraîchissements de page.
**Questions stratégiques sur la persistance des données :**
Avant dimplémenter la persistance, considérez ces facteurs critiques :
| Question | Contexte application bancaire | Impact de la décision |
|----------|-------------------|----------------|
| **Les données sont-elles sensibles ?** | Solde de compte, historique des transactions | Choisir des méthodes de stockage sécurisées |
| **Combien de temps doit-il persister ?** | État de connexion vs. préférences temporaires de l'interface utilisateur | Sélectionnez la durée de stockage appropriée |
| **Le serveur en a-t-il besoin ?** | Jetons d'authentification vs. paramètres de l'interface utilisateur | Déterminez les exigences de partage |
**Options de stockage dans le navigateur :**
Les navigateurs modernes offrent plusieurs mécanismes de stockage, chacun conçu pour des cas d'utilisation différents :
**APIs de stockage principales :**
1. **[`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage)** : Stockage [clé/valeur persistant](https://en.wikipedia.org/wiki/Key%E2%80%93value_database)
- **Persiste** les données indéfiniment entre les sessions du navigateur
- **Survit** aux redémarrages du navigateur et de l'ordinateur
- **Ciblé** sur le domaine spécifique du site web
- **Parfait** pour les préférences utilisateur et états de connexion
2. **[`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage)** : Stockage temporaire pour la session
- **Fonctionne** de manière identique à localStorage durant la session active
- **S'efface** automatiquement à la fermeture de l'onglet du navigateur
- **Idéal** pour les données temporaires qui ne doivent pas persister
3. **[Cookies HTTP](https://developer.mozilla.org/docs/Web/HTTP/Cookies)** : Stockage partagé avec le serveur
- **Envoyés automatiquement** avec chaque requête au serveur
- **Parfaits** pour les jetons d'[authentification](https://en.wikipedia.org/wiki/Authentication)
- **Limités** en taille et peuvent impacter les performances
**Exigence de sérialisation des données :**
`localStorage` et `sessionStorage` ne stockent que des [chaînes de caractères](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) :
```js
// Convertir les objets en chaînes JSON pour le stockage
const accountData = { user: 'john', balance: 150 };
localStorage.setItem('account', JSON.stringify(accountData));
// Analyser les chaînes JSON en objets lors de la récupération
const savedAccount = JSON.parse(localStorage.getItem('account'));
```
**Comprendre la sérialisation :**
- **Convertit** les objets JavaScript en chaînes JSON via [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)
- **Reconstruit** les objets depuis JSON via [`JSON.parse()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse)
- **Gère** automatiquement les objets imbriqués complexes et les tableaux
- **Échoue** avec les fonctions, valeurs undefined et références circulaires
> 💡 **Option avancée** : Pour des applications hors ligne complexes avec de grands jeux de données, considérez l'API [`IndexedDB`](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Elle offre une base de données complète côté client, mais requiert une mise en œuvre plus complexe.
```mermaid
quadrantChart
title Options de Stockage Navigateur
x-axis Complexité Faible --> Complexité Élevée
y-axis Durée Courte --> Durée Longue
quadrant-1 Outils Professionnels
quadrant-2 Persistance Simple
quadrant-3 Stockage Temporaire
quadrant-4 Systèmes Avancés
localStorage: [0.3, 0.8]
sessionStorage: [0.2, 0.2]
HTTP Cookies: [0.6, 0.7]
IndexedDB: [0.9, 0.9]
Memory Variables: [0.1, 0.1]
```
### Tâche : Implémenter une persistance avec localStorage
Implémentons un stockage persistant pour que les utilisateurs restent connectés jusqu'à déconnexion explicite. Nous utiliserons `localStorage` pour stocker les données de compte entre les sessions.
**Étape 1 : Définir la configuration du stockage**
```js
const storageKey = 'savedAccount';
```
**Ce que fournit cette constante :**
- **Crée** un identifiant cohérent pour nos données stockées
- **Évite** les erreurs typographiques dans les clés de stockage
- **Facilite** la modification de la clé de stockage si besoin
- **Suit** les meilleures pratiques pour un code maintenable
**Étape 2 : Ajouter la persistance automatique**
Ajoutez cette ligne à la fin de la fonction `updateState()` :
```js
localStorage.setItem(storageKey, JSON.stringify(state.account));
```
**Analyse de ce qui se passe ici :**
- **Convertit** l'objet compte en chaîne JSON pour le stockage
- **Enregistre** les données en utilisant notre clé de stockage cohérente
- **S'exécute** automatiquement à chaque mise à jour d'état
- **Garantit** la synchronisation constante des données stockées et de l'état actuel
> 💡 **Avantage architectural** : Comme toutes les mises à jour d'état passent par `updateState()`, ajouter la persistance a seulement demandé une ligne. Cela montre l'intérêt d'une bonne architecture !
**Étape 3 : Restaurer l'état au chargement de l'application**
Créez une fonction d'initialisation pour restaurer les données sauvegardées :
```js
function init() {
const savedAccount = localStorage.getItem(storageKey);
if (savedAccount) {
updateState('account', JSON.parse(savedAccount));
}
// Notre code d'initialisation précédent
window.onpopstate = () => updateRoute();
updateRoute();
}
init();
```
**Comprendre le processus d'initialisation :**
- **Récupère** les données de compte précédemment sauvegardées dans localStorage
- **Analyse** la chaîne JSON pour retrouver un objet JavaScript
- **Met à jour** l'état via notre fonction de mise à jour contrôlée
- **Restaure** automatiquement la session utilisateur au chargement de la page
- **S'exécute** avant les mises à jour de route pour garantir l'état disponible
**Étape 4 : Optimiser la route par défaut**
Modifiez la route par défaut pour exploiter la persistance :
Dans `updateRoute()`, remplacez :
```js
// Remplacer : return navigate('/login');
return navigate('/dashboard');
```
**Pourquoi ce changement est pertinent :**
- **Tire parti** efficacement de notre nouveau système de persistance
- **Permet** au tableau de bord de gérer les vérifications d'authentification
- **Redirige** automatiquement vers la connexion si aucune session sauvegardée n'existe
- **Crée** une expérience utilisateur plus fluide
**Tester votre implémentation :**
1. Connectez-vous à votre application bancaire
2. Actualisez la page du navigateur
3. Vérifiez que vous restez connecté et sur le tableau de bord
4. Fermez et rouvrez votre navigateur
5. Naviguez à nouveau vers votre application et confirmez que vous êtes toujours connecté
🎉 **Félicitations** : Vous avez implémenté avec succès une gestion de l'état persistant ! Votre application se comporte désormais comme une application web professionnelle.
### 🎯 Vérification pédagogique : Architecture de persistance
**Compréhension architecturale** : Vous avez mis en place une couche sophistiquée de persistance, équilibrant expérience utilisateur et complexité de gestion des données.
**Concepts clés maîtrisés** :
- **Sérialisation JSON** : conversion d'objets complexes en chaînes stockables
- **Synchronisation automatique** : les changements d'état déclenchent la persistance
- **Récupération de session** : restauration du contexte utilisateur après interruption
- **Persistance centralisée** : une seule fonction de mise à jour gère tout le stockage
**Lien avec l'industrie** : Ce modèle de persistance est fondamental pour les Progressive Web Apps (PWA), applications hors ligne et expériences mobiles modernes. Vous développez des capacités de niveau production.
**Question de réflexion** : Comment modifieriez-vous ce système pour gérer plusieurs comptes utilisateurs sur un même appareil ? Prenez en compte les implications de confidentialité et sécurité.
## Équilibrer persistance et fraîcheur des données
Notre système de persistance maintient avec succès les sessions utilisateur, mais introduit un nouveau défi : la vétusté des données. Lorsque plusieurs utilisateurs ou applications modifient les mêmes données serveurs, les informations locales mises en cache deviennent obsolètes.
Cette situation rappelle les navigateurs vikings qui utilisaient à la fois des cartes d'étoiles stockées et des observations célestes actuelles. Les cartes fournissaient une constance, mais les navigateurs avaient besoin d'observations fraîches pour tenir compte des conditions changeantes. De même, notre application a besoin à la fois d'un état utilisateur persistant et de données serveurs actualisées.
**🧪 Découverte du problème de fraîcheur des données :**
1. Connectez-vous au tableau de bord avec le compte `test`
2. Exécutez cette commande dans un terminal pour simuler une transaction externe :
```sh
curl --request POST \
--header "Content-Type: application/json" \
--data "{ \"date\": \"2020-07-24\", \"object\": \"Bought book\", \"amount\": -20 }" \
http://localhost:5000/api/accounts/test/transactions
```
3. Actualisez la page du tableau de bord dans le navigateur
4. Observez si la nouvelle transaction apparaît
**Ce que ce test démontre :**
- **Montre** comment le stockage local peut devenir "obsolète"
- **Simule** des scénarios réels où des données changent hors de votre application
- **Révèle** la tension entre persistance et fraîcheur des données
**Le défi de l'obsolescence des données :**
| Problème | Cause | Impact utilisateur |
|----------|-------|--------------------|
| **Données obsolètes** | localStorage n'expire jamais automatiquement | Les utilisateurs voient des informations périmées |
| **Modifications serveurs** | D'autres apps/utilisateurs modifient les mêmes données | Vues incohérentes entre plateformes |
| **Cache vs. réalité** | Le cache local ne correspond pas à l'état serveur | Mauvaise expérience utilisateur et confusion |
**Stratégie de solution :**
Nous allons implémenter un modèle de "rafraîchissement au chargement" qui équilibre les avantages de la persistance avec le besoin de données fraîches. Cette approche maintient une expérience fluide tout en assurant la précision des données.
```mermaid
sequenceDiagram
participant U as Utilisateur
participant A as Application
participant L as stockageLocal
participant S as Serveur
U->>A: Ouvre l'application
A->>L: Charger l'état sauvegardé
L-->>A: Retourner les données en cache
A->>U: Afficher l'interface immédiatement
A->>S: Récupérer des données fraîches
S-->>A: Retourner les données actuelles
A->>L: Mettre à jour le cache
A->>U: Mettre à jour l'interface avec des données fraîches
```
### Tâche : Implémenter un système de rafraîchissement des données
Nous allons créer un système qui récupère automatiquement les données fraîches du serveur tout en conservant les bénéfices de notre gestion d'état persistante.
**Étape 1 : Créer une fonction de mise à jour des données du compte**
```js
async function updateAccountData() {
const account = state.account;
if (!account) {
return logout();
}
const data = await getAccount(account.user);
if (data.error) {
return logout();
}
updateState('account', data);
}
```
**Comprendre la logique de cette fonction :**
- **Vérifie** si un utilisateur est actuellement connecté (`state.account` existe)
- **Redirige** vers la déconnexion si aucune session valide n'est trouvée
- **Récupère** les données fraîches du compte depuis le serveur via `getAccount()`
- **Gère** les erreurs serveur en déconnectant les sessions invalides
- **Met à jour** l'état avec les données fraîches via notre système contrôlé de mise à jour
- **Déclenche** la persistance automatique dans localStorage via `updateState()`
**Étape 2 : Créer un gestionnaire de rafraîchissement pour le tableau de bord**
```js
async function refresh() {
await updateAccountData();
updateDashboard();
}
```
**Ce que réalise cette fonction de rafraîchissement :**
- **Coordonne** la récupération des données et la mise à jour de l'interface
- **Attend** le chargement des données fraîches avant mise à jour de l'affichage
- **Garantit** que le tableau de bord affiche les informations les plus récentes
- **Maintient** une séparation claire entre gestion des données et mise à jour UI
**Étape 3 : Intégrer au système de routes**
Modifiez votre configuration de route pour déclencher le rafraîchissement automatiquement :
```js
const routes = {
'/login': { templateId: 'login' },
'/dashboard': { templateId: 'dashboard', init: refresh }
};
```
**Fonctionnement de cette intégration :**
- **Exécute** la fonction de rafraîchissement à chaque chargement de la route du tableau de bord
- **Assure** l'affichage de données fraîches quand l'utilisateur navigue sur le tableau de bord
- **Maintient** la structure de route existante tout en ajoutant la fraîcheur des données
- **Fournit** un modèle cohérent d'initialisation spécifique aux routes
**Tester votre système de rafraîchissement de données :**
1. Connectez-vous à votre application bancaire
2. Exécutez la commande curl évoquée précédemment pour créer une nouvelle transaction
3. Actualisez la page du tableau de bord ou naviguez ailleurs puis revenez
4. Vérifiez que la nouvelle transaction apparaît immédiatement
🎉 **Parfait équilibre atteint** : Votre application combine désormais l'expérience fluide d'un état persistant avec la précision de données serveurs fraîches !
## 📈 Votre timeline de maîtrise de la gestion d'état
```mermaid
timeline
title Parcours Professionnel de Gestion d'État
section Reconnaissance du Problème
Diagnostic des Problèmes d'État
: Identifier les problèmes de perte de session
: Comprendre les problèmes de mises à jour dispersées
: Reconnaître les besoins architecturaux
section Fondation Architecturale
Conception d'État Centralisé
: Créer des objets d'état unifiés
: Mettre en œuvre des modèles de mise à jour contrôlés
: Établir des principes immuables
Mises à Jour Prédictibles
: Maîtriser l'utilisation de Object.freeze()
: Construire des systèmes facilitant le débogage
: Créer des modèles évolutifs
section Maîtrise de la Persistance
Intégration localStorage
: Gérer la sérialisation JSON
: Mettre en œuvre la synchronisation automatique
: Assurer la continuité de la session
Équilibre de Fraîcheur des Données
: Traiter les défis de la datation
: Construire des mécanismes de rafraîchissement
: Optimiser performance vs précision
section Modèles Professionnels
Systèmes Prêts pour la Production
: Mettre en œuvre la gestion des erreurs
: Créer des architectures maintenables
: Suivre les meilleures pratiques du secteur
Capacités Avancées
: Prêt pour l'intégration de frameworks
: Préparé pour les besoins complexes en état
: Fondation pour les fonctionnalités en temps réel
```
**🎓 Étape finale** : Vous avez développé un système complet de gestion d'état utilisant les mêmes principes que Redux, Vuex et autres bibliothèques professionnelles. Ces modèles passent des apps simples aux applications d'entreprise.
**🔄 Capacités avancées :**
- Prêt à maîtriser des frameworks de gestion d'état (Redux, Zustand, Pinia)
- Préparé à implémenter des fonctionnalités temps réel avec WebSockets
- Équipé pour construire des Progressive Web Apps hors ligne d'abord
- Solide fondation pour des patterns avancés comme machines à états et observateurs
## Défi GitHub Copilot Agent 🚀
Utilisez le mode Agent pour relever ce défi :
**Description :** Implémentez un système complet de gestion d'état avec fonctionnalités d'annulation/rétablissement pour l'application bancaire. Ce défi vous fera pratiquer des concepts avancés tels que le suivi historique des états, les mises à jour immuables et la synchronisation interface utilisateur.
**Consigne :** Créez un système de gestion d'état amélioré incluant : 1) un tableau historique d'états suivi, 2) des fonctions undo/redo permettant de revenir aux états antérieurs, 3) des boutons UI undo/redo sur le tableau de bord, 4) une limite maximale de 10 états pour éviter les problèmes mémoire, et 5) un nettoyage approprié de l'historique à la déconnexion. Assurez-vous que undo/redo fonctionne avec les changements de solde et persiste après actualisation du navigateur.
En savoir plus sur [mode agent](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode).
## 🚀 Challenge : Optimisation du stockage
Votre implémentation gère désormais efficacement les sessions utilisateurs, le rafraîchissement des données et la gestion d'état. Cependant, réfléchissez à l'optimalité de notre approche actuelle entre efficacité du stockage et fonctionnalité.
À l'image des maîtres d'échecs qui distinguent pièces essentielles et pions sacrificiels, une gestion d'état efficace requiert d'identifier quelles données doivent persister versus celles qui doivent toujours être fraîches depuis le serveur.
**Analyse d'optimisation :**
Évaluez votre implémentation actuelle de localStorage en considérant ces questions stratégiques :
- Quelle est l'information minimale requise pour maintenir l'authentification utilisateur ?
- Quelles données changent suffisamment souvent pour que la mise en cache locale soit peu intéressante ?
- Comment optimiser le stockage sans dégrader l'expérience utilisateur ?
Ce type d'analyse architecturale distingue les développeurs expérimentés qui prennent en compte à la fois fonctionnalité et efficience dans leurs solutions.
**Stratégie d'implémentation :**
- **Identifiez** les données essentielles à persister (probablement juste l'identification utilisateur)
- **Modifiez** votre implémentation localStorage pour ne stocker que ces données critiques
- **Assurez** le chargement systématique des données fraîches à chaque visite du tableau de bord
- **Testez** que l'expérience utilisateur reste la même avec cette approche optimisée
**Réflexion avancée :**
- **Comparez** les compromis entre le stockage des données complètes du compte versus uniquement les jetons d'authentification
- **Documentez** vos décisions et justifications pour l'équipe future
Ce défi vous aidera à penser comme un développeur professionnel mêlant expérience utilisateur et efficience applicative. Prenez le temps d'expérimenter différentes approches !
## Quiz post-conférence
[Quiz post-conférence](https://ff-quizzes.netlify.app/web/quiz/48)
## Devoir
[Implémenter la boîte de dialogue « Ajouter une transaction »](assignment.md)
Voici un exemple de résultat après avoir complété le devoir :
![Capture d'écran montrant un exemple de boîte de dialogue "Ajouter une transaction"](../../../../translated_images/fr/dialog.93bba104afeb79f1.webp)
---
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
**Avis de non-responsabilité** :
Ce document a été traduit à laide du service de traduction automatique [Co-op Translator](https://github.com/Azure/co-op-translator). Bien que nous nous efforcions dassurer lexactitude, veuillez noter que les traductions automatiques peuvent contenir des erreurs ou des inexactitudes. Le document original dans sa langue dorigine doit être considéré comme la source faisant foi. Pour les informations critiques, une traduction professionnelle effectuée par un humain est recommandée. Nous déclinons toute responsabilité en cas de malentendus ou de mauvaises interprétations résultant de lutilisation de cette traduction.
<!-- CO-OP TRANSLATOR DISCLAIMER END -->