JSJS Memo🎙️ Coach

Introduction React et Fonctionnalité

Reactjs est un bibliothèque javascript frontale, elle suit l'approche du composant utilisé pour créer les composants d'interfaces utilisateur réutilisables.

Fonctionnalité du ReactJs

  • JSX (Javascript Xml) : il s'agit d'une extension du React qui permet d'Ă©crire le code Javascript similaire au HTML(Cela nous permet d'Ă©crire du HTML dans JavaScript et de le placer dans le DOM sans utiliser de fonctions comme appendChild() ou createElement().
  • Virtual DOM : est un objet javascript qui reprĂ©sente en mĂ©moire le vrai DOM(Le DOM virtuel est essentiel pour React car il permet Ă  l'application de mettre Ă  jour l'interface utilisateur en ne modifiant que les Ă©lĂ©ments qui ont rĂ©ellement changĂ©. Cela permet d'Ă©viter des mises Ă  jour coĂ»teuses du DOM rĂ©el, qui peuvent ralentir les performances de l'application. En utilisant un DOM virtuel, React peut anticiper les mises Ă  jour et cibler efficacement les modifications nĂ©cessaires, ce qui amĂ©liore les performances globales de l'application.)

(En React, lorsque l'état d'un composant change, React utilise le Virtual DOM pour déterminer les modifications nécessaires au DOM réel et met à jour le DOM de manière sélective, en effectuant uniquement les manipulations nécessaires. Cette approche permet d'améliorer les performances de l'application, car elle évite les manipulations coûteuses et répétées du DOM.)

Concrètement, lorsque le Virtual DOM détecte un changement d'état d'un composant, il crée une nouvelle représentation virtuelle du DOM (appelée Virtual DOM) qui reflète l'état actuel de l'interface utilisateur. Cette nouvelle représentation est comparée avec la représentation précédente, afin de déterminer les différences entre les deux.

Une fois que les différences ont été identifiées, React met à jour le DOM réel en effectuant uniquement les manipulations nécessaires. Par exemple, si un élément de texte a été modifié, React mettra à jour uniquement le contenu de cet élément, plutôt que de reconstruire l'ensemble de la page.

Pour mettre à jour le DOM réel, React utilise des méthodes DOM standard, telles que createElement, appendChild, removeChild, setAttribute, removeAttribute,

React utilise un algorithme de réconciliation pour mettre à jour le DOM réel.

  • Composants sont des Ă©lĂ©ments constitutifs des applications, il divise l'interface utilisateur et petits code indĂ©pendants et rĂ©utilisables.

Quelles sont les limites de React ?

  • React n'est pas un framework Ă  part entière car ce n'est qu'une bibliothèque.

uniDireactionnel data flow

uniDireactionnel data flow : En React, la propagation des données (ou "data flow") est unidirectionnelle. c'est à dire que les données sont transmises d'un composant parent à un composant enfant, mais jamais l'inverse. Cette architecture de données unidirectionnelle facilite la gestion de l'état de l'application et permet d'éviter les effets secondaires imprévus.

DOM virtuel

Le DOM virtuel : est un objet javascript qui représente en mémoire le vrai DOM.Il permet à l'application de mettre à jour l'interface utilisateur en ne modifiant que les éléments qui ont réellement changé. Cela permet d'éviter des mises à jour coûteuses du DOM réel, qui peuvent ralentir les performances de l'application.

Lorsque le state ou props d'un composant React changent, React utilise un processus appelé "réconciliation" pour mettre à jour le DOM virtuel. Cela implique la création d'un nouvel arbre du DOM virtuel qui représente l'interface utilisateur mise à jour, puis la comparaison du nouvel arbre avec l'ancien afin de déterminer les modifications à apporter au DOM réel du navigateur. Une fois que React a déterminé quelles parties du DOM virtuel doivent être mises à jour, il effectue l'ensemble minimal de modifications nécessaires pour mettre à jour le DOM du navigateur, sans avoir à mettre à jour l'ensemble de l'interface utilisateur. Ce processus est beaucoup plus rapide et efficace que la mise à jour directe du DOM du navigateur, car il minimise la quantité de travail que le navigateur doit effectuer. Le DOM virtuel facilite également le raisonnement sur le comportement d'un composant, puisqu'il fournit une séparation nette entre l'état du composant et sa présentation. Cela permet aux développeurs de se concentrer sur l'écriture d'un code propre et modulaire, sans avoir à se préoccuper des détails de la mise à jour de l'interface utilisateur.

Réconciliation

Réconciliation est un mécanisme qui permet de mettre à jour le DOM réel en fonction des changements apportés à l'interface utilisateur.

Le processus de réconciliation est déclenché chaque fois qu'un composant change d'état ou de props. Lorsque cela se produit, React crée une nouvelle représentation virtuelle du DOM, qui reflète l'état actuel de l'interface utilisateur. Cette représentation est comparée avec la représentation précédente pour déterminer les différences entre les deux.

(Pour ce faire, il utilise un algorithme de réconciliation, qui calcule le nombre minimal de manipulations DOM nécessaires pour mettre à jour l'interface utilisateur, en évitant les manipulations coûteuses et répétées.)

L'algorithme de réconciliation est basé sur la méthode de "diffing" (ou comparaison), qui consiste à comparer les nœuds de l'ancien DOM avec les nœuds du nouveau DOM pour déterminer les changements à apporter. Cette technique permet d'optimiser les performances en évitant de re-rendre les parties de l'interface utilisateur qui n'ont pas changé.

Si la reconciliation échoue, React gère les erreurs qui peuvent survenir pendant le rendu d'un composant à l'aide Error Boundaries.

Bonne pratique

  • Utiliser des clĂ©s stables et uniques pour les listes
  • Mises Ă  jour immuables de l'Ă©tat: Ne mutilez pas les objets/tableaux ; crĂ©ez de nouvelles rĂ©fĂ©rences.
  • Ne pas mĂ©langer contrĂ´lĂ© / non contrĂ´lĂ©: Un input qui passe de value dĂ©fini Ă  undefined (ou inversement) dĂ©clenche des incohĂ©rences.

Diffing

Diffing fait référence à l'algorithme de différenciation qu'utilise React pour identifier les différences entre l'arbre d'éléments virtuels actuel et l'arbre d'éléments virtuels précédent. Cet algorithme permet d' optimiser la mise à jour du DOM réel du navigateur, minimisant le nombre de modifications nécessaires et améliorant les performances de l'application

React Fiber

React Fiber : le moteur de rendu Fiber est basé sur un modèle de traitement asynchrone qui utilise un algorithme de "reconciliation" pour déterminer les mises à jour à effectuer sur l'interface utilisateur. L'algorithme de réconciliation analyse les changements dans l'état des composants et détermine les mises à jour à effectuer de manière incrémentale, en divisant le travail en petites tâches. Cela permet à React de traiter les mises à jour plus rapidement.

Hydratation

L'hydratation consiste à rendre une page interactive après son affichage. Le serveur génère d'abord le HTML. L'utilisateur peut déjà voir la page. Ensuite React télécharge le JavaScript nécessaire et rattache les événements aux éléments affichés.

Par exemple un bouton est visible immédiatement mais il ne devient réellement cliquable qu'après l'hydratation.

L'un des objectifs modernes de Next.js est de réduire la quantité de JavaScript à hydrater. Moins on hydrate, plus l'application est rapide.

Pourquoi moins on hydrate, plus la performance?

Parce que l'hydratation est une opération coûteuse pour le navigateur. Quand une page Next.js est rendue côté serveur, le navigateur reçoit déjà le HTML. Ce HTML peut être affiché immédiatement. Mais ce HTML est uniquement statique. Pour qu'il devienne interactif (boutons, formulaires, événements...), React doit hydrater la page. Cette hydratation comporte plusieurs étapes :

  • TĂ©lĂ©charger le bundle JavaScript.
  • Parser le JavaScript.
  • L'exĂ©cuter.
  • RecrĂ©er l'arbre React.
  • Comparer cet arbre avec le DOM dĂ©jĂ  affichĂ©.
  • Attacher tous les Ă©vĂ©nements (onClick, onChange, etc.).

Toutes ces étapes utilisent du CPU. Plus il y a de composants à hydrater, plus le navigateur travaille.

Si Interrompue ou échoué

Si l'hydratation est interrompue, plusieurs problèmes peuvent survenir, car React ne parvient pas à prendre le contrôle complet de l'interface générée côté serveur.

  • L'application devient partiellement ou totalement non interactive

Les composants s'affichent bien (grâce au SSR), mais les interactions (clics, formulaires, navigation, etc.) ne fonctionnent pas. Exemple : un bouton est visible mais ne déclenche aucune action au clic.

  • Des erreurs de synchronisation DOM peuvent apparaĂ®tre

React tente de "matcher" l'arbre HTML du serveur avec l'état prévu du client. Si l'hydratation est interrompue ou échoue (ex: à cause d'un décalage de données, de rendu conditionnel, ou d'une erreur JS), React détecte un "mismatch".

Cela peut entraîner : Des warnings dans la console (du type "Text content did not match"). Une reconstruction complète du DOM côté client (ce qu'on essaie justement d'éviter pour des raisons de performance).

Render

Render() est une fonction utilisée pour renvoyer le code HTML qui sera affiché dans le composant. Lorsqu'un composant est créé ou que son state/props change, React appelle la méthode render() pour mettre à jour l'interface utilisateur. La méthode renvoie un élément React, qui est une description de ce qui doit être rendu, y compris le type de composant à rendre et ses propriétés.

Props

Props (propriétés) sont des objets qui stocke les valeurs attributs. Ils ne doivent pas être changés car immutable pour garantir la clarté, la cohérence et la prévisibilité dans une applications

Props Children

Props.children est une props utilisé pour passer du contenu textuel ou des éléments de React en tant qu'enfant, ou Children c'est un moyen de transmettre un contenu qui doit être rendu dans un composant enfant

Render Props (Alternative cloneElement)

Render props" (ou "render props" en anglais) sont une technique pour partager du code entre des composants en passant une fonction en tant que propriété (prop) à un composant enfant. La fonction passée en tant que prop renvoie un élément (ou plusieurs éléments) qui sera affiché à l'écran.

Children Vs Render Props

En React, les "props children" et les "render props" sont deux techniques pour passer des composants en tant que propriétés (props) à un composant parent, mais ils sont utilisés dans des situations différentes.

  • Les "props children" sont une technique pour passer des composants enfants Ă  un composant parent en les incluant directement dans la structure JSX. Les "props children" sont souvent utilisĂ©s lorsque le composant parent doit envelopper les composants enfants avec des balises HTML supplĂ©mentaires ou pour rendre le composant parent plus facile Ă  lire.
  • Les "render props" sont une technique pour passer une fonction de rendu en tant que props Ă  un composant parent. La fonction de rendu renvoie un Ă©lĂ©ment (ou plusieurs Ă©lĂ©ments) qui seront affichĂ©s Ă  l'Ă©cran. Les "render props" sont souvent utilisĂ©s lorsque le composant parent doit transmettre une certaine logique de rendu au composant enfant.

State

State est un objet qui contient des données et des informations sur le composant. Il peut être modifié pendant la durée de vie du composant. Lorsque State change, React rend à nouveau le composant, mettant à jour l'interface utilisateur pour refléter les nouvelles données. On devra toujours utiliser la méthode setState() pour mettre à jour l'état. En effet, React utilise la méthode setState() pour suivre les modifications apportées par le State du composant, et modifier directement l'objet state peut entraîner un comportement inattendu tels que le DOM ne sera pas mis à jour, les effets sécondaires.

Ref

Ref permet d'accéder à un élément DOM sans utiliser target. Les Ref fournissent un moyen d'interagir avec le DOM, sans avoir à utiliser d'autres méthodes telles que findDOMNode() ou à transmettre des props aux composants enfants. Il est créé avec la méthode React.createRef(), qui renvoie un objet Ref. Et l' objet Ref peut ensuite être attaché à un élément React en tant qu'attribut ref).

Conséquence

Rupture avec la philosophie de React: React encourage une approche déclarative pour gérer les interactions avec le DOM et le state. L'utilisation excessive de refs peut introduire une logique impérative qui va à l'encontre de cette philosophie, rendant le code plus difficile à maintenir. Augmentation des risques de bugs: Si les refs sont utilisés dans des situations où React ou un autre composant met aussi à jour l'élément concerné, cela peut entraîner des conflits. Il y a un problèmes de synchronisation

Moments où l'utilisation des refs est appropriée :

  • Interactions directes avec le DOM (focus, scroll, animations).
  • Stockage de valeurs mutables qui ne nĂ©cessitent pas de re-render.
  • IntĂ©gration de bibliothèques tierces ou manipulation complexe du DOM.

ForwardRef

forwardRef est une fonction qui permet de transférer une référence (ref) à un composant enfant qui n'accepte pas de références en tant que propriété. Le transfert de références est important dans certains cas, par exemple pour gérer le focus d'un élément de formulaire ou pour effectuer des mesures sur des éléments d'interface utilisateur. En général, les références sont transmises à des éléments d'interface utilisateur en utilisant la propriété ref.

Compound Component Pattern

Le pattern Compound Component permet de communiquer entre le composant parent avec ses enfants, en séparant la logique et l'interface utilisateur.

Dans le pattern Compound Component, au lieu de transmettre le state par le props, on transmet les éléments en tant qu'enfants d'un élément parent.

Props Vs State

| ----- | ----- | | Immutable | Mutable | | Permet de transmettre les données d'un composant à un autre en tant qu'argument (Allows data to be passed from one component to another as an argument) | Contient les informations sur les composants (Contains information on the components) | | Le composant d'enfant peut accéder aux props (The child component can access the props) | N'est pas accessible aux composants d'enfant (Not accessible to the child's components) |

Composants Fonctionnels

Ce sont des fonctions JavaScript qui acceptent des props comme arguments et retournent du JSX pour définir l'interface utilisateur.

Ils utilisent les hooks (useState, useEffect, etc.) pour gérer l'état ou les effets de cycle de vie.

Composant Classe

Ce sont des classes ES6 qui étendent React.Component et implémentent une méthode render pour retourner du JSX. Ils gèrent le state en tant que propriété interne. Ils fournissent des méthodes de cycle de vie comme componentDidMount, componentDidUpdate, etc.

Fonctionnels Vs Classe

Le composant fonctionnel permet d'utiliser des hooks pour ajouter des fonctionnalités comme l'état ou les effets. Le composant classe, les hooks ne sont pas utilisables avec les composants de classe.

Le composant fonctionnel est défini comme des fonctions JavaScript simples. Le composant classe est basés sur des classes ES6 étendant React.Component.

Composants Contrôlés

Le composants contrôlé: c'est un composant dont la source de vérité (la valeur affichée et son évolution) est gérée par React, via son state ou via des props provenant d'un parent.

Dans le cas des formulaires :

  • La valeur de l'input est liĂ©e Ă  une variable de state.
  • Toute mise Ă  jour passe par un handler qui modifie ce state.
  • L'UI reflète toujours l'Ă©tat actuel.

Inconvénient : plus de re-renders → peut être coûteux si le formulaire est énorme (optimisation possible avec useMemo / React.memo)

Controlled Components

Composants Non Contrôlés

Les composants non contrôlés : c'est un composant dont la valeur n'est pas gérée par React, C'est le DOM qui garde l'état interne (par ex. la valeur d'un \<input>). On utilise une ref pour lire ou modifier le valeur seulement quand on en a besoin via ref.current.value. Inconvénients :

  • Pas de synchronisation en temps rĂ©el avec React.
  • Validation et mise Ă  jour de l'UI plus compliquĂ©es.
  • Difficile Ă  tester car il faut manipuler le DOM.

Uncontrolled Components

Composants Stateful

Un composant Stateful est un composant qui gère un state interne, c'est-à-dire des données qui peuvent changer au fil du temps. Il contient souvent une logique métier ou des interactions avec l'utilisateur qui nécessitent de modifier l'état.

Composants Stateless

Un composant Stateless est un composant qui ne gère pas d'état interne (state).il se contente de recevoir des props et de les afficher. Il est souvent utilisé pour des composants "présentationnels" (pure UI), car il ne contient que de la logique d'affichage.

Différence entre Hook et classe

  • Pas de class et donc pas de keyword class, pas d'instanciation et donc on ne s'embĂŞte pas avec de la logique de class js.
  • Pas de constructor (No the contructor)
  • Pas de this (ça peut faire Ă©viter quelques bugs)
  • Beaucoup plus simple Ă  lire et donc Ă  dĂ©bugger. (On Ă©vite le code verbeux des class)
  • Une manipulation beaucoup plus simple et performante des Ă©vĂ©nements et changements de props.
  • Hook est utilisĂ© dans les composants fonctionnels de React.
  • Classe est dans les composants basĂ©s sur les classes de React.
  • Hook n'a pas encore introduit certaines fonctions tels que : — getSnapshotBeforeUpdate() — getDerivedStateFromError() — componentDidCatch()

Voir \=> [Pourquoi on utilise HOOk que classe](https://oclock.io/blog/4708/pourquoi-se-former-aux-hooks-de-react#:~:text=Les%20hooks%20sont%20la%20nouvelle,utilisation%20d'%C3%A9tat%20local)

PureComponent

PureComponent est une classe qui possède déjà sa méthode ShoudComponentUpdate qui se charge d'effectuer une comparaison de surface et l'état local. C'est-à-dire qu'il compare les valeurs lors de la recherche de type de données primitifs et compare les références d'objets.

L'utilisation Purecomponent :

State/Props du composant est un objet immuable State / Props ne doit pas avoir l'objet imbriqué à plusieurs niveaux

Conseils Pro : Tous les composants enfant de PureComponent doivent également être des composants purs ou fonctionnels.

Higher Order Component (HOC)

HOC (Composant d'ordre Supérieur) est une fonction qui accepte un composant et renvoie un nouveau composant.

Lors du développement, il est courant de créer des composants qui partagent des comportements ou une logique similaire. Pour éviter de répéter du code et respecter le principe DRY ("Don't Repeat Yourself"), il est important de trouver une abstraction permettant de centraliser cette logique dans un seul endroit et de la partager entre les composants. Le HOC est une solution idéale pour créer cette abstraction, en encapsulant la logique réutilisable et en l'appliquant à plusieurs composants.

Key et importance

Importance of keys

  • Keys aident Ă  identifier les Ă©lĂ©ments qui ont Ă©tĂ© ajoutĂ©s, modifiĂ©s ou supprimĂ©s.
  • Sans Keys, React ne comprend pas l'ordre ou l'unicitĂ© de chaque Ă©lĂ©ment.

Éviter

L'index du tableau change dès qu'on insère/supprime/tri/re-filtre → React associe le mauvais composant au mauvais item, ce qui crée des bugs d'état.

Duplication de keys

Avec des keys dupliquées, React ne sait plus quelle instance correspond à quel item : l'état se mélange, et la suppression peut viser le mauvais élément.

LifeCycle de composant

Cycle de vie de composant

  • Constructor()
  • Render()
  • ComponentDidMount()
  • ShouldComponentUpdate()
  • Render()
  • ComponentDidUpdate()

Component phase

Les Phases de composant

  • Montage (Mounting) : Cette Ă©tape se produit lorsque le composant est créé et ajoutĂ© Ă  l'arbre de composants React. Les mĂ©thodes de cycle de vie correspondantes sont : constructor(), getDerivedStateFromProps(), render(), et componentDidMount().
  • Mise Ă  jour (Updating) : Cette Ă©tape se produit chaque fois que le composant est mis Ă  jour, gĂ©nĂ©ralement en rĂ©ponse Ă  une modification des propriĂ©tĂ©s (props) ou de l'Ă©tat (state) du composant. Les mĂ©thodes de cycle de vie correspondantes sont : getDerivedStateFromProps(), shouldComponentUpdate(), render(), getSnapshotBeforeUpdate(), et componentDidUpdate().
  • DĂ©montage (Unmounting) : Cette Ă©tape se produit quand le composant est retirĂ© de l'arbre de composants React, parce qu'il n'est plus nĂ©cessaire ou que son parent est lui-mĂŞme retirĂ©. La mĂ©thode de cycle de vie correspondante est : componentWillUnmount().

Fragment

Fragment permet de regrouper la liste de plusieurs enfants sans ajouter un nœud supplémentaire du DOM. Un fragment est utile lorsqu'on a besoin d'ajouter plusieurs éléments enfants à un composant, mais que on ne veut pas ajouter un élément parent supplémentaire dans le DOM, qui pourrait affecter la structure et le style de la page. fragment peut aussi améliorer les performances de l' application en évitant la création d'éléments DOM inutiles.

ProtoType

En React, PropTypes est une validation de type pour les props (propriétés) qui permet de définir les types de données attendus pour chaque prop d'un composant. PropTypes permet de vérifier que les données transmises à un composant correspondent au type de données attendu, et de fournir des messages d'erreur clairs si ce n'est pas le cas

React Hooks

What are React Hooks

Hooks ont un nouvel ajout à React dans la version 16.8 qui vous permet d'utiliser l'état et d'autres fonctionnalités de React, comme les méthodes de cycle de vie, sans écrire de classe.

Les Hooks sont des functions qui permettent de bénéficier de fonctionnalités React qu'on pouvait avoir que via une classe : Ex un state local, les cycles de vie, les contextes, etc.

  • Hook permet de refactorer des composants complexes et Ă  tester.
  • Hook supprime la complexitĂ© inhĂ©rente de classe telle que l'initialisation de constructeur et les fonctions de liaison aux composants pour ses mĂ©thodes y aient accès dans l'instance de composant
  • Hook nous permettent d'organiser la logique Ă  l' intĂ©rieur d' un composant en unitĂ©s rĂ©utilisables et isolĂ©es .
  • Rules - Règles Ă  suivre lors de l'utilisation de React Hooks ?
  • React Hooks doit ĂŞtre appelĂ© uniquement au niveau supĂ©rieur. Il n'est pas permis de les appeler Ă  l'intĂ©rieur des fonctions, boucles ou conditions imbriquĂ©es.
  • Il est autorisĂ© d'appeler les crochets uniquement Ă  partir des composants de la fonction Reactjs
  • Basic React Hooks

Règles Hook

  • Toujours en haut
  • Toujours dans un composant ou hook
  • Jamais dans condition / boucle

Pourquoi "jamais dans une condition ou boucle" ? Parce que React identifie les hooks uniquement par leur ordre d'appel, pas par leur nom.

UseState

UseState est un Hook en React qui permet d'avoir des variables d'état dans les composants fonctionnels. Il permet de créer un état interne dans une fonction, ce qui permet de stocker des données qui peuvent être modifiées et qui peuvent déclencher un nouveau rendu du composant. Le state est une donnée interne au composant qui peut être modifiée par le biais de la fonction retournée par useState.

const [state, setState] \= useState(initialState);

UseEffect

UseEffet qui permet de gérer les effets de bord dans les composants fonctionnels

Le but est d'exécuter la logique des side-effects à l'intérieur de la fonction de callback qui utilise l'argument des dépendances pour contrôler quand on souhaite que side-effects s'exécute.

UseEffet permet de gérer le cycle de vie de composant comme à une combinaison de ComponentDidMount, componentDidUpdate, et componentWillUnmount. useEffect(callback[, dependencies]); Si les dépendances ne sont pas fournies, le side-effects s'exécute après chaque rendu. S'il s'agit d'un tableau vide [], le side-effects s'exécute une fois après le rendu initial.

useEffect(callback[, dependencies]);

Il existe deux types :

  • Effects sans Cleanup
  • Effects avec Cleanup

UseLayoutEffect

C'est similaire qu'à useEffect(), la différence qu'il s'exécutera après que React a validé les mises à jour du DOM. Il est utilisé dans de rares cas, lorsqu'on veut calculer la distance entre les éléments après une mise à jour ou effectuer d'autres calculs

UseContext

Le contexte fournit un moyen de transmettre des données à travers l'arborescence des composants sans avoir à transmettre les props manuellement à chaque niveau.

Le Contexte est basé sur deux composants:

  • Provider: permet de fournir les donnĂ©es du contexte
  • Consumer: permet de les rĂ©cupĂ©rer.
  • Provider
  • Consumer.

Avantages :

  • Solution native Ă  la librairie React, elle est disponible dès que l'on commence une nouvelle application React
  • Prise en main très facile
  • Il est possible d'intĂ©grer des contextes plus "locaux", c'est-Ă -dire qui n'englobent pas l'intĂ©gralitĂ© de l'application mais plutĂ´t une petite quantitĂ© de composants : cela permet de segmenter la logique de l'application

Inconvénients :

  • L'API Context n'est pas adaptĂ©e pour des changements frĂ©quents de state (par exemple, pour la valeur d'un champ de texte)
  • Tous les composants consommant le contexte vont ĂŞtre re-render Ă  chaque changement du stage global proposĂ© par le contexte, mĂŞme si l'information qu'ils utilisent n'est pas changĂ©e

UseCallback

useCallback renverra une version mémorisée du Callback qui ne change que si l'une des dépendances a changé. Ceci est utile lors de la transmission de callback à des composants enfants optimisés qui reposent sur l'égalité des références pour éviter les rendus inutiles.

UseCallback permet de mémoriser callback des fonctions, afin qu'elles ne soient pas recréées à chaque nouveau rendu.) Il est similaire à useMemo, sauf qu'il renvoie une fonction et useMemo renvoie une valeur.

const memoizedCallback \= useCallback( () \=> { doSomething(a, b); }, [a, b], );

UseMemo

useMemo recalculera la valeur mémoïsée seulement si une des entrées a changé. Cette optimisation permet d'éviter des calculs coûteux à chaque rendu.

const memoizedValue \= useMemo(() \=> computeExpensiveValue(a, b), [a, b]);

Pourquoi useMemo partout est une mauvaise idée ?

Parce que useMemo consomme aussi de la mémoire et ajoute une logique supplémentaire. Si le calcul est simple, le coût du mémo peut être supérieur au coût du recalcul.

UseMemo Vs UseCallBack

useMemo et useCallback sont deux hooks utilisés pour optimiser les performances des composants fonctionnels useMemo : Mémorise et retourne une valeur useCallback : Mémorise et retourne une fonction

UseMemo et React.Memo

useMemo et React.memo qui permettent d'optimiser les performances de l'application en réduisant le nombre de rendus inutiles. useMemo est un hook qui permet de "mémoriser" (c'est-à-dire de mettre en cache) le résultat d'un calcul coûteux et de ne le recalculer que lorsque les dépendances ont changé. useMemo est souvent utilisé pour éviter de recalculer des valeurs dérivées à chaque fois qu'un composant est rendu.

React.memo est une fonction qui permet de "mémoriser" un composant et d'éviter de le rendre à nouveau s'il reçoit les mêmes props. React.memo est souvent utilisé pour éviter des rendus inutiles de composants qui n'ont pas changé.

Pourquoi React.memo n'est pas une solution miracle ?

Parce qu'il ajoute lui aussi un coût de comparaison des props. Je l'utilise uniquement lorsqu'un composant est coûteux à rendre et que ses props sont relativement stables. Je mesure avant d'optimiser.

UseRef

Chaque fois qu' on met à jour un state local ou un props, le composant s'affiche à nouveau pour afficher les derniers éléments en fonction de la mise à jour de l'état. Afin d'aborder le re-rendu du composant, on utilise une variable locale via useRef hook. useRef renvoie un objet ref, dont la .current propriété est initialisée à l'argument passé ( initialValue). L'objet renvoyé persistera pendant toute la durée de vie du composant.

const refContainer \= useRef(initialValue);

useState Vs UseRef

useState met à jour l'UI en déclenchant un re-render, tandis que useRef stocke une valeur sans provoquer de re-render.

CreateRef Vs UseRef

useRef et createRef sont deux méthodes pour créer des références à des éléments d'interface utilisateur en React. createRef est utilisé dans les composants de classe, tandis que useRef est utilisé dans les composants fonctionnels. useRef renvoie également la même instance d'objet pour chaque rendu, tandis que createRef crée une nouvelle instance à chaque appel.

UseImperativeHandle

useImperativeHandle c'est un hook qui permet à un composant fonctionnel d'exposer des méthodes ou des propriétés personnalisées à son parent lorsqu'il est utilisé avec une ref. Il est utilisé en combinaison avec React.forwardRef.

Props Drilling

Parfois, lors du développement d'applications React, il est nécessaire de transmettre des données d'un composant situé plus haut dans la hiérarchie à un composant profondément imbriqué. Pour transmettre des données entre de tels composants, on transmet via props à partir d'un composant source et continuons à transmettre props au composant suivant dans la hiérarchie jusqu'à ce qu'on atteint le composant profondément imbriqué.

Error boundaries

Introduites dans la version 16 de React, Error boundaries nous permettent de détecter les erreurs qui se produisent lors de la phase de rendu. Error boundaries est un composant utilisant l'une ou les deux méthodes suivantes : static getDerivedStateFromError et componentDidCatch.

Portal

Les portails pour afficher des composants enfants dans un nœud DOM qui existe en dehors de la hiérarchie DOM du composant parent (ReactDOM.createPortal(child, container)

Redux

Redux est une bibliothèque pour la gestion d'état dans les applications React. Elle fournit un moyen de stocker et de gérer l'état global de l'application, qui peut être partagé entre différents composants.

Redux utilise un store centralisé pour stocker l'état global de l'application, qui peut être accédé à partir de n'importe quel composant. Les données dans le store ne peuvent être modifiées que par des "actions", qui sont envoyées au store. Ces actions sont des objets simples qui décrivent un changement souhaité avec un type et, parfois, des données supplémentaires.

Le store met à jour l'état de l'application en fonction de l'action reçue à l'aide de "reducers".

Les reducers sont des fonctions pures qui prennent l'état actuel et une action comme arguments et renvoient un nouvel état. Chaque reducer gère une partie spécifique de l'état global de l'application. Lorsqu'une action est dispatchée et que l'état est mis à jour, le store déclenche un nouveau rendu des composants qui dépendent de cet état.

[Liens schema architectu](https://www.linkedin.com/pulse/redux-architecture-overview-priyesh-chandra-1c/)re

Fonctionnement du Redux( How does Redux work)

Redux génère l'objet javascript appelé le store Store contient le globale State de composant Actions qui représentent les différentes interactions que l'utilisateur peut faire, il s'agit de déclencheur. Enfin les actions se transmettent dans les Reducers qui définissent les actions du State

Dispatch

Les actions sont envoyées au Store à l'aide de la méthode dispatch(). Lorsqu'une action est envoyée, elle est transmise au Reducer, qui déterminent comment mettre à jour l'état de l'application.

Connect

Dans Redux, connect est une fonction fournie par la bibliothèque react-redux qui permet aux composants React de se connecter au Store Redux.

La fonction connect est utilisée pour créer des composants d'ordre supérieur (HOC) qui enveloppent un composant de base et lui fournissent un accès au Store Redux. Elle prend deux arguments : mapStateToProps et mapDispatchToProps.

  • mapStateToProps est une fonction qui prend l'Ă©tat actuel du magasin et le met en correspondance avec les props du composant enveloppĂ©. Elle renvoie un objet qui spĂ©cifie les parties de l'Ă©tat qui doivent ĂŞtre transmises au composant.
  • mapDispatchToProps est une fonction facultative qui fait correspondre les crĂ©ateurs d'actions aux props. Elle peut ĂŞtre utilisĂ©e pour simplifier le processus de distribution des actions vers le magasin.

3 règles ou principaux du redux

  • Le global state est unique
  • Le state est en lecture seule (si on modifie le state, on doit passer par l'Actions. Sinon redux ne sera pas que ça n'a pas changĂ©, il y a une forte chance que le Framework ne redĂ©signe pas la vue et c'est pas traçable)
  • Reducers sont des fonctions pures ( car le reducers sont des fonctions qui collent les changements et ne doivent pas prendre en compte des effects de bord, pas des requĂŞtes ajax dĂ©pendante du temps, le Reducers ne fait que du synchrone)

CombineReducer

CombineReducer est une fonction qui permet de combiner plusieurs Reducers en un seul Reducer root. Le Reducer root est ensuite utilisé pour créer le store de l'application. L'utilité de combineReducers est de diviser la gestion de l'état de l'application en plusieurs Reducer spécialisés, chacun étant responsable de gérer une partie spécifique de l'état. Cela permet de séparer les préoccupations et de faciliter la compréhension et la maintenance du code.

ApplyMiddleWare

applyMiddleware est une fonction qui permet d'appliquer des middleware à un store Redux. Les middleware sont des fonctions qui sont exécutées à chaque fois qu'une action est dispatchée vers le store. L'utilité de applyMiddleware est de permettre la gestion des actions asynchrones et la mise en place de traitements additionnels lors de la réception d'une action. Les middleware peuvent intercepter les actions avant qu'elles n'atteignent les Reducers, et effectuer des tâches telles que la gestion de requêtes asynchrones, la journalisation, le traitement de la logique métier, la surveillance de l'état de l'application,

Asynchrone avec Thunk & promise([VOIR PLUS)](https://redux.js.org/tutorials/fundamentals/part-6-async-logic)

En Redux, les requêtes asynchrones peuvent être traitées à l'aide de middleware tels que "redux-thunk" ou "redux-saga". L'architecture typique pour traiter les requêtes asynchrones en Redux consiste à créer trois types d'actions pour chaque requête : une action de demande, une action de succès et une action d'échec.

Avantages :

  • Architecture des responsabilitĂ©s (reducers, actions, …) bien dĂ©finie et constante
  • Des extensions de navigateur comme "Redux DevTools" sont disponibles et permettent de facilement dĂ©bugger l'intĂ©gration de Redux dans un projet utilisant React

Inconvénients :

  • Difficile Ă  adopter lorsqu'on dĂ©bute sur React
  • Librairie externe Ă  React : les deux packages nĂ©cessaires (redux & react-redux) reprĂ©sentent des donnĂ©es supplĂ©mentaires Ă  tĂ©lĂ©charger pour l'utilisateur final

Redux Vs ApiContext

Le choix entre Redux et Context API dépend de la taille et de la complexité de l'application, ainsi que des préférences de développement de l'équipe. Pour les applications de grande envergure nécessitant une gestion d'état robuste, Redux est souvent le choix privilégié. Pour les applications plus petites à modérées, et quand on évite la complexité supplémentaire, l'API Context pourrait être suffisante.

  • Performance : Redux peut conduire Ă  une meilleure performance pour les grandes applications car il optimise les mises Ă  jour d'Ă©tat et peut Ă©viter des rendus inutiles, tandis que l'API Context peut causer des rendus supplĂ©mentaires si elle n'est pas implĂ©mentĂ©e avec prĂ©caution.
  • ComplexitĂ© : Redux a une courbe d'apprentissage plus raide et peut surcompenser pour des applications plus petites, tandis que l'API Context est plus facile Ă  apprendre et Ă  intĂ©grer.

Je pars du plus simple. Pour un état global limité (thème, langue, user) et peu de mises à jour, Context suffit.

Dès qu'on a un état volumineux/partagé, des updates fréquentes, des middlewares ou besoin d'un outillage solide (DevTools, time-travel, normalisation), Redux devient plus pertinent. Côté perf, Redux limite mieux les rerenders via des sélecteurs, alors que Context doit être découpé pour ne pas tout rerendre.

Redux-thunk Vs saga

redux-thunk et redux-saga sont deux middlewares de Redux qui permettent de gérer des opérations asynchrones dans une application. Ils ont des approches différentes pour résoudre le même problème: comment interagir avec l'API et effectuer des effets secondaires en gardant les principes de Redux.

  • ComplexitĂ©: Redux-Saga est plus complexe Ă  comprendre, surtout pour les dĂ©veloppeurs moins familiers avec les fonctions gĂ©nĂ©rateurs de JavaScript, tandis que Redux-Thunk utilise des fonctions qui retournent des fonctions, ce qui est gĂ©nĂ©ralement plus simple.
  • TestabilitĂ©: Redux-Saga est souvent louĂ© pour la facilitĂ© de test de ses sagas grâce aux effets dĂ©claratifs, contrairement aux thunks qui nĂ©cessitent de mocker les dispatch et getState.

Mode Strict

StrictMode est un outil ajouté dans la version 16.3 de React pour mettre en évidence les problèmes potentiels dans une application. Il effectue des vérifications supplémentaires sur l'application.

StrictMode aide actuellement avec les problèmes :

  • Identification des composants avec des mĂ©thodes de cycle de vie non sĂ©curisĂ©es
  • Avertissement sur l'utilisation de findDOMNode
  • Avertissement concernant l'utilisation de l'API contextuelle hĂ©ritĂ©e (car l'API est sujette aux erreurs).

Concurrent Mode

Le Concurrent Mode est une fonctionnalité de React 18 qui permet à plusieurs mises à jour de l'interface utilisateur de se faire simultanément. Cela permet à React de travailler sur plusieurs tâches en même temps, interrompre et reprendre ces tâches sans bloquer le fil principal du navigateur, ce qui améliore significativement la fluidité et la réactivité des applications. Pour utiliser le Concurrent Mode, on devra l'activer dans l' application React.

Optimisation React

Pour optimiser les performances de l'application React

  • Utilisation de useMemo( )
  • Utilisation de React.PureComponent
  • Lazy Loading

Performance React

Pour obtenir la version de production la plus efficace avec Brunch, installez l'extension [terser-brunch](https://github.com/brunch/terser-brunch) :

  • Brunch- Browserify
  • Rollup-webpack

Éviter la réconciliation Pour éviter la création de nœuds DOM superflus et l'accès excessif aux nœuds existants, dans la mesure où ces opérations sont plus lentes que sur des objets JavaScript.

Quand les props ou l'état local d'un composant changent, React décide si une mise à jour du DOM est nécessaire en comparant l'élément renvoyé avec l'élément du rendu précédent. Quand ils ne sont pas égaux, React met à jour le DOM.

Même si React ne met à jour que les nœuds DOM modifiés, refaire un rendu prend un certain temps. Dans la plupart des cas ce n'est pas un problème, mais si le ralentissement est perceptible, vous pouvez accélérer le processus en surchargeant la méthode shouldComponentUpdate du cycle de vie, qui est déclenchée avant le démarrage du processus de rafraîchissement. L'implémentation par défaut de cette méthode renvoie true, laissant ainsi React faire la mise à jour

Si vous savez que dans certaines situations votre composant n'a pas besoin d'être mis à jour, vous pouvez plutôt renvoyer false depuis shouldComponentUpdate afin de sauter le rendu, et donc l'appel à la méthode render() sur ce composant et ses enfants. Le plus souvent, plutôt que d'écrire manuellement shouldComponentUpdate(), vous pouvez plutôt choisir d'étendre [React.PureComponent](https://fr.reactjs.org/docs/react-api.html#reactpurecomponent). Ça revient à implémenter shouldComponentUpdate() avec une comparaison superficielle des propriétés et état actuels et précédents.

Données immuables

On évite de modifier directement les valeurs que vous utilisez dans les props ou l'état local

ES6 offre la [syntaxe de décomposition](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Op%C3%A9rateurs/Syntaxe_d%C3%A9composition) (spread operator, NdT) pour les tableaux, ce

qui facilite ce type d'opération. Si vous utilisez Create React App, cette syntaxe est disponible par défaut.

En évitant de modifier l'objet original, nous pouvons utiliser la méthode [Object.assign](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Object/assign) :

[La syntaxe de décomposition des objets](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Op%C3%A9rateurs/Syntaxe_d%C3%A9composition) facilite la mise à jour d'objets sans pour autant les modifier :

Virtualiser les listes longues Si votre application génère d'importantes listes de données (des centaines ou des milliers de lignes), nous vous conseillons d'utiliser la technique de « fenêtrage » (windowing, NdT). Cette technique consiste à n'afficher à tout instant qu'un petit sous-ensemble des lignes, ce qui permet de diminuer considérablement le temps nécessaire au rendu des composants ainsi que le nombre de nœuds DOM créés.

[react-window](https://react-window.now.sh/) et [react-virtualized](https://bvaughn.github.io/react-virtualized/) sont des bibliothèques populaires de gestion du fenêtrage.

Mémorisation des composant React

La mémorisation est une technique d'optimisation en stockant les résultats d'appels de fonction et en renvoyant le résultant mis en cache lorsque les mêmes entrées se reproduisent. Une fonction mémorisée est généralement plus rapide car si la fonction est appelée avec les mêmes valeurs que la précédente, au lieu d'exécuter une logique de fonction, elle récupère le résultat du cache

Element Vs Component

En React, un élément (Element) et un composant (Component) sont deux concepts différents.

Un élément (Element) est un objet JavaScript qui décrit ce que l'on souhaite afficher à l'écran. Il peut être créé en utilisant la syntaxe JSX ou en utilisant la fonction React.createElement(). Les éléments sont des objets immuables qui représentent l'interface utilisateur et ne peuvent pas être modifiés une fois qu'ils ont été créés.

Un composant (Component) est une fonction ou une classe qui peut prendre des propriétés (props) en entrée et renvoyer un élément (Element) en sortie. Les composants peuvent être réutilisables et modulaires, et ils sont utilisés pour décrire l'interface utilisateur de manière déclarative.

Presentational and Container component

Presentational and Container component est utilisée en React pour séparer les responsabilités de présentation et de gestion de l'état d'un composant.

Un composant de présentation est responsable de la présentation de l'interface utilisateur. Il ne contient pas de logique métier ou de gestion d'état complexe. Les composants de présentation sont des composants fonctionnels et sont souvent réutilisables.

Un composant de conteneur, en revanche, est responsable de la logique métier et de la gestion de l'état d'un composant. Il peut encapsuler un ou plusieurs composants de présentation et fournir des données et des fonctions pour les manipuler.

L'avantage de cette pattern est qu'elle permet de séparer les responsabilités de présentation et de gestion de l'état d'un composant, ce qui facilite la réutilisation et la maintenance du code. Les composants de présentation peuvent être réutilisés dans d'autres composants de conteneur, tandis que les composants de conteneur peuvent être spécialisés pour différents cas d'utilisation.

Suspense

React Suspense est une fonctionnalité dans React 16.6 pour gérer l'état de chargement asynchrone des composants dans une application React. Elle permet de suspendre le rendu d'un composant jusqu'à ce que toutes les dépendances asynchrones (telles que le chargement de données à partir d'une API) soient résolues. Avant l'introduction de React Suspense, les développeurs devaient gérer manuellement l'état de chargement et les erreurs lors de l'utilisation de données asynchrones dans leurs composants. Cela nécessite souvent l'utilisation de techniques telles que les callbacks, les promesses (promises) ou les bibliothèques externes. Lorsque vous utilisez des composants asynchrones tels que React.lazy (pour le chargement paresseux des composants) ou ReactDOM.createRoot (pour le rendu racine), React Suspense peut détecter automatiquement quand une partie de l'interface utilisateur est en attente de données et afficher un indicateur de chargement pendant ce temps.

Pourquoi plusieurs Suspense sont souvent meilleurs qu'un seul ?

Je veux éviter qu'une ressource lente bloque toute l'expérience utilisateur. Je préfère que chaque section devienne indépendante.

Batch State

React batch est un mécanisme interne de React qui permet de regrouper plusieurs mises à jour d'état en une seule opération de re-rendering.

Si on clique sur la fonction handleClick, le composant se rechargera une seule fois. Cela est dû au fait que les trois fonctions de mise à jour de l'état (SetName, SetLastName, SetFirstName) sont appelées de manière consécutive dans la fonction, et React regroupe les mises à jour d'état avant de déclencher un seul rechargement du composant. Par conséquent, même s'il y a trois mises à jour d'état, elles seront regroupées et entraîneront un seul rechargement du composant.

onClick={ \=> X} et onClick={X}

onClick={() \=> X()} : Dans cette approche, une fonction fléchée est utilisée comme callbacl onClick. Lorsque l'événement onClick se produit, la fonction fléchée est invoquée en tant que nouvelle fonction à chaque fois. Cela signifie que chaque rendu du composant crée une nouvelle instance de la fonction. Cela peut entraîner des problèmes de performances si la fonction est utilisée dans un composant avec un rendu fréquent, car une nouvelle fonction doit être créée à chaque fois, ce qui peut avoir un impact sur les performances et la consommation de mémoire.

onClick={X} : Dans cette approche, la référence à la fonction X elle-même est utilisée comme rappel onClick. Lorsque l'événement onClick se produit, la fonction X est invoquée directement. La référence à la fonction n'est pas modifiée à chaque rendu du composant. Cela peut être plus efficace en termes de performances, car la même référence à la fonction est utilisée à chaque fois, évitant ainsi la création de nouvelles fonctions à chaque rendu.

SPA

SPA est une implémentation d'application web qui ne charge qu'un seul document web, puis met à jour le contenu du corps de ce document via des API JavaScript telles que [XMLHttpRequest](https://developer.mozilla.org/fr/docs/Web/API/XMLHttpRequest) et [Fetch](https://developer.mozilla.org/fr/docs/Web/API/Fetch_API) lorsqu'un contenu différent doit être affiché. Cela permet aux utilisateurs d'utiliser des sites web sans charger de nouvelles pages entières à partir du serveur, ce qui peut entraîner des gains de performances et une expérience plus dynamique, avec certains inconvénients tels que le référencement (SEO), plus d'efforts nécessaires pour maintenir l'état, mettre en œuvre la navigation et mesurer les performances.

Code splitting

code splitting consiste à séparer le code en plusieurs paquets ou composants qui peuvent être chargés à la demande ou en parallèle. c'est-à-dire qu'ils ne sont pas chargés tant qu'ils ne sont pas nécessaires. Les avantages du code spitting sont : La vitesse de chargement du site devient plus rapide. Le temps d'interaction s'améliore.

En react pour effectuer code splitting:

  • Avec React.Lazy : Cette fonction vous permet d'importer un composant de manière dynamique et de l'insĂ©rer dans un composant Suspense
  • SĂ©paration de route avec React Router : en sĂ©parant le code par route

Déclaration Style CSS

L'utilisation du CSS avec React peut se faire de plusieurs manières:

Standard CSS: Il faut juste d'importer une feuille de style CSS dans un fichier de composant

Avantages: C'est la méthode traditionnelle et la plus connue par les développeurs. Séparation des préoccupations : Le CSS est séparé du JavaScript, ce qui peut être plus lisible pour certains développeurs. Facilité d'utilisation : Il n'y a pas besoin d'apprendre de nouvelles syntaxes ou méthodologies.

Inline CSS: Inline CSS est souvent écrit sous forme d'objet JavaScript, où les propriétés CSS sont appliquées directement sur l'élément JSX

Avantages: Portée locale : Le style ne s'applique qu'à l'élément sur lequel il est placé, évitant ainsi les conflits. Contrôle dynamique : Il est facile d'altérer les styles en fonction de l'état ou des props du composant.

CSS Modules

CSS Modules permettent de créer des fichiers CSS qui sont transformés en un objet où les classes ont des noms locaux uniques. Vous les utilisez en important le fichier CSS comme un module dans votre composant JavaScript.

Avantages: Portée locale par défaut : Évite les conflits de nom de classe et l'effet de cascade involontaire. Composition : Permet de composer les styles en combinant différentes classes.

Styled Components

Styled Components

Styled Components permet de créer des composants React avec des styles attachés, en utilisant des chaînes de caractères taguées pour le CSS.

Avantages:

  • Styles encapsulĂ©s : Les styles sont attachĂ©s spĂ©cifiquement aux composants, rĂ©duisant les conflits et l'effet de cascade.
  • JavaScript et CSS en un seul endroit : Favorise la cohĂ©sion en gardant la logique et les styles ensemble.
  • Thème et props : Les styles peuvent ĂŞtre facilement thĂ©matisĂ©s et modifiĂ©s en fonction des props.

Automatic Batching

Avantage : L'automatisation du regroupement des mises à jour dans React 18 permet de réduire le nombre de rendus inutiles et améliore ainsi les performances. Cela signifie que plusieurs mises à jour d'état peuvent être combinées en une seule, réduisant ainsi les re-rendus de composants. Problème résolu : Avant React 18, les mises à jour d'état asynchrones (comme celles dans les promesses, les timeouts, etc.) n'étaient pas toujours regroupées automatiquement. Cela pouvait entraîner des re-rendus multiples pour chaque mise à jour d'état, diminuant ainsi les performances.

Suspense sur le server

Avantage : L'introduction de Suspense sur le serveur permet de retarder le rendu de certaines parties de l'interface jusqu'à ce que toutes les données nécessaires soient disponibles. Cela améliore l'expérience utilisateur en réduisant les temps de chargement perçus, et rend possible le streaming du HTML au client. Problème résolu : Avant cette fonctionnalité, les applications Server-Side Rendering (SSR) attendaient que toutes les données soient prêtes avant d'envoyer une page complète au client. Cela pouvait entraîner des temps de chargement plus longs. Avec Suspense sur le serveur, les applications peuvent envoyer des parties du HTML avant que toutes les données ne soient disponibles, améliorant ainsi le rendu progressif.

Server component et client Component

Avantage : React introduit la distinction entre les composants serveur et client, permettant aux composants de fonctionner soit sur le serveur (où le JavaScript n'est pas nécessaire), soit sur le client (pour des interactions côté client). Cela réduit la quantité de JavaScript envoyé au navigateur, optimisant les performances. Problème résolu : Avant cette fonctionnalité, tous les composants React devaient être rendus côté client, même ceux qui n'avaient pas d'interactions directes avec l'utilisateur, ce qui augmentait la taille des bundles JavaScript. Désormais, les composants qui n'ont pas besoin d'être interactifs peuvent rester sur le serveur.

useId

Avantage : Le hook useId permet de générer des identifiants uniques, qui sont cohérents entre le serveur et le client. Cela est crucial pour les scénarios où des composants nécessitent des identifiants uniques pour les attributs comme aria-*, id dans des formulaires, ou des éléments interactifs. Problème résolu : Avant useId, générer des identifiants uniques à la fois côté serveur et côté client pouvait entraîner des problèmes de dé-synchronisation, notamment dans le rendu SSR où les identifiants générés côté serveur pouvaient différer de ceux générés côté client, causant des erreurs de réhydratation.

useTransition

Avantage : useTransition permet de différer certaines mises à jour pour qu'elles soient considérées comme « non urgentes », ce qui aide à maintenir une interface utilisateur fluide. Cela permet par exemple de prioriser les interactions immédiates (comme les clics ou les saisies) tout en retardant des mises à jour moins cruciales, comme le chargement de données. Problème résolu : Dans les versions antérieures de React, toutes les mises à jour d'état avaient la même priorité, ce qui pouvait entraîner des blocages dans l'interface utilisateur lorsque des opérations coûteuses étaient effectuées, rendant l'expérience utilisateur moins réactive.

useSyncExternalStore

Avantage : Ce hook standardise la manière dont les composants peuvent se synchroniser avec des stores d'état externes (comme Redux, Zustand, etc.). Il permet de garantir que l'état du store externe est correctement synchronisé avec React et améliore la compatibilité avec les rendus concurrents. Problème résolu : Auparavant, chaque bibliothèque externe gérait cette synchronisation de manière différente, ce qui pouvait entraîner des comportements imprévisibles ou inefficaces, notamment avec les nouvelles fonctionnalités comme le mode concurrent. useSyncExternalStore assure une meilleure intégration avec l'architecture concurrente de React.

Webpack

Webpack est un outil de développement utilisé pour le bundling (ou empaquetage) de fichiers JavaScript pour les applications. Il nous aider à gérer les dépendances et à optimiser le code pour les déploiements en production

Il prend les fichiers JavaScript et leurs dépendances (comme des modules ES6, CommonJS, ou AMD) et les combine en un ou plusieurs bundles. Un bundle est un seul fichier ou un groupe de fichiers qui peuvent être chargés par le navigateur.

Gestion des Dépendances : Webpack analyse les dépendances de votre projet. Il suit les relations entre les fichiers pour comprendre comment ils sont connectés. Cela inclut non seulement le JavaScript, mais aussi les CSS, les images, les polices, et même les fichiers HTML.

Transformation de Fichiers : Webpack utilise des loaders pour transformer les fichiers. Par exemple, Babel peut être utilisé pour transpiler du code JavaScript ES6 en ES5, Sass ou Less pour compiler du CSS, et d'autres loaders pour gérer des fichiers spécifiques comme les images ou les polices. Plugins : Webpack a un système de plugins puissant qui peut être utilisé pour étendre ses fonctionnalités. Les plugins peuvent accomplir une variété de tâches comme l'optimisation des fichiers, la gestion des assets, la définition de variables d'environnement, etc.

Angular Vs React

Angular Angular est un framework complet, Il est orienté pour les applications SPA (Single Page Application).

Avantages :

Framework complet : Angular fournit une solution complète avec des outils intégrés comme le système de routage, le binding bidirectionnel des données, les services, les formulaires réactifs, etc.

Opinionné : Angular suit une architecture stricte et guide les développeurs à travers des bonnes pratiques standardisées . TypeScript : Angular est conçu en TypeScript, ce qui apporte une meilleure gestion des erreurs, une complétion de code améliorée, et une meilleure maintenabilité pour les projets de grande échelle. Structure modulaire : Angular facilite la création de composants modulaires, réutilisables, et testables.

Inconvénients : Courbe d'apprentissage : Angular peut sembler complexe au début, surtout avec la nécessité de comprendre TypeScript, la syntaxe des décorateurs, et les concepts comme les modules et les injecteurs de dépendance. Performance : Parfois, Angular peut être plus lourd pour des applications légères en comparaison avec React. Verbosité : Le code dans Angular peut être verbeux, nécessitant plusieurs fichiers pour des composants simples.

ReactJS React est une bibliothèque JavaScript,Il est utilisé pour la création d'interfaces utilisateur (UI) avec une approche basée sur les composants.

Avantages : Flexibilité : React est une bibliothèque légère et flexible. Il ne dicte pas comment structurer une application, permettant aux développeurs de choisir les outils (par ex., gestion des états avec Redux, React Router pour le routage).

JSX : React utilise JSX, qui combine JavaScript et HTML dans le même fichier, ce qui rend l'écriture des composants plus intuitive.

Performances : La gestion optimisée du DOM via le "Virtual DOM" permet des mises à jour rapides et efficaces de l'interface, ce qui se traduit souvent par de meilleures performances sur des applications légères.

Inconvénients : Pas de structure imposée : La flexibilité de React peut être un inconvénient pour les grandes équipes ou projets, car elle peut entraîner des incohérences dans l'architecture de l'application.

Écosystème fragmenté : Contrairement à Angular qui a tout intégré, avec React il faut choisir ses propres outils (gestion d'état, routage, etc.), ce qui peut être déroutant pour les débutants. JSX : Si JSX est apprécié par certains, d'autres trouvent que mélanger HTML et JavaScript peut nuire à la lisibilité.

e.preventDefault

e.preventDefault() est une méthode utilisée en JavaScript pour empêcher le comportement par défaut d'un événement. En React, la raison d'utiliser e.preventDefault() est de garder le contrôle sur la logique des événements dans une application.

Dans React, l'objet e dans e.preventDefault() fait référence à un SyntheticEvent, qui est une abstraction des événements du DOM natifs. Ce système d'événements garantit une compatibilité inter-navigateurs et offre les mêmes propriétés et méthodes que les événements natifs (comme preventDefault(), stopPropagation(), etc.).

React 19

  • Nouveau compilateur React

React 19 intègre un nouveau compilateur qui optimise automatiquement les re-rendus des composants. C'est plus nécessaire d'ajouter manuellement des hooks tels que useMemo, useCallback et React.memo, facilitant ainsi la gestion des performances.

  • Actions

Les Actions simplifient la gestion des mutations de données et des soumissions de formulaires. Elles automatisent la gestion des états pendants, des erreurs, des mises à jour optimistes et des requêtes séquentielles, réduisant ainsi le code boilerplate nécessaire pour ces opérations.

  • Composants Serveur (Server Components) et Actions Serveur

Les Composants Serveur permettent de rendre des composants côté serveur, améliorant les performances et le référencement SEO. Les Actions Serveur offrent la possibilité aux composants clients d'appeler des fonctions asynchrones exécutées sur le serveur, simplifiant ainsi la gestion des opérations côté serveur.

  • Nouveaux hooks

React 19 introduit plusieurs nouveaux hooks :

use(): permet de lire des ressources asynchrones directement dans le rendu, suspendant le rendu jusqu'à la résolution de la promesse.

useFormStatus(): offre un accès à l'état d'un formulaire parent, utile pour gérer les états de soumission et les erreurs sans avoir à propager manuellement les props.

useActionState(): facilite la gestion des états pendants et des erreurs lors de l'exécution d'actions asynchrones.

useOptimistic(): aide à gérer les mises à jour optimistes de l'interface utilisateur pendant les mutations de données asynchrones, offrant une meilleure expérience utilisateur

Activity

ViewTransition

addTransitionType

Atomic design

Les concepts Atom, Molecule, Organism, Template et Page proviennent de la méthodologie Atomic Design, créée par Brad Frost. Cette approche est utilisée dans les design systems pour organiser et structurer les composants d'une interface utilisateur en niveaux logiques, afin de faciliter leur réutilisation et leur gestion.

Atom: Les atoms (ou atomes) sont les éléments indivisibles d'une interface utilisateur. Ce sont des composants de base qui ne peuvent pas être décomposés davantage.

Exemples : Un bouton (\<button>), Un champ de texte (\<input>), Une icĂ´ne

Utilité : Ils servent de blocs de construction pour tous les autres composants.

Molecule: Une molecule (ou molécule) est une combinaison de plusieurs atoms qui travaillent ensemble pour former une unité fonctionnelle simple. Les molécules introduisent déjà une certaine logique ou interactivité.

Exemples : Une barre de recherche : composée d'un champ de texte (\<input>) et d'un bouton (\<button>). Un tag avec une icône : une icône (\<svg>) et un texte stylisé.

Utilité : Les molécules créent des composants simples mais significatifs, qui peuvent être réutilisés à différents endroits.

Organism: Un organism (ou organisme) est une combinaison de molecules (et parfois d'atoms) qui fonctionnent ensemble pour créer des sections complexes de l'interface.

Exemples :Un en-tête (header) : peut inclure un logo (molecule), une barre de navigation (molecule), et un champ de recherche (molecule). Une carte produit dans un e-commerce : composée d'une image, d'un titre, d'un prix et d'un bouton d'achat.

Utilité : Les organismes représentent des blocs fonctionnels de haut niveau dans votre design system. Ils permettent de construire des sections complètes de pages.

Template: template est une structure globale ou un agencement qui combine plusieurs organismes et les place dans un cadre spécifique pour créer la structure d'une page.

Exemples : Une page produit dans un e-commerce : composée d'un en-tête (organisme), d'un carrousel de produits (organisme), et d'un pied de page. Une page d'accueil avec une bannière, une liste d'articles et une section "Contact".

Utilité : Les templates définissent la disposition et l'agencement des composants sans contenir de données finales. Ils sont souvent statiques, servant de squelette ou de maquette.

Page: Une page est une instance concrète d'un template, avec des données réelles ou des contenus spécifiques. Elle représente l'étape finale du design, celle qui est directement visible par l'utilisateur.

Exemples : Une page produit pour un T-shirt spécifique (avec un nom, un prix, une image réelle, etc.). Une page d'accueil avec des articles et images réels provenant d'une base de données.

Utilité : Les pages montrent à quoi ressemble réellement l'interface avec des données concrètes. Elles permettent de valider que les templates, organismes, molécules et atomes fonctionnent correctement ensemble.

Css optimisation

Il a plusieurs technique pour optimiser le css tels que:

Optimisation du poids des fichiers CSS

  • Minification : Supprimer tous les espaces, tabulations, commentaires inutiles (cssmin, csso, etc.).
  • Compression GZIP ou Brotli :Configurer le serveur pour compresser les fichiers CSS avant de les envoyer au navigateur.Purge du CSS inutile (PurgeCSS, UnCSS) :Retirer toutes les règles CSS qui ne sont jamais utilisĂ©es sur le site.
  • ConcatĂ©nation : Combiner plusieurs fichiers CSS en un seul pour rĂ©duire le nombre de requĂŞtes HTTP (attention aux stratĂ©gies modernes HTTP/2 qui parfois favorisent plusieurs petits fichiers).

Optimisation en architecture CSS

  • MĂ©thodologies de structuration :Utiliser BEM (Block-Element-Modifier), OOCSS (Object-Oriented CSS), ou SMACSS pour garder un code maintenable et prĂ©visible.
  • Utiliser les prĂ©processeurs (SASS, LESS) intelligemment : Mais sans crĂ©er d'inflation de CSS avec des imbrications (nesting) trop profondes.
  • Modulariser le CSS : Dans les projets modernes (React, Vue), utiliser des systèmes de CSS Modules, Styled Components pour Ă©viter les fuites de styles.

Best Practices CSS

  • Adopter une mĂ©thodologie : Utiliser BEM (Block Element Modifier), OOCSS, SMACSS, ou Atomic Design pour rendre ton CSS clair, modulaire et prĂ©visible.
  • Structurer les fichiers CSS : Diviser le CSS en plusieurs fichiers logiques : base/ (reset, typographie, variables), components/ (boutons, cartes, formulaires), layouts/ (grilles, en-tĂŞte, pied de page), pages/ (styles spĂ©cifiques Ă  une page)
  • Limiter la profondeur des sĂ©lecteurs : Maximum 2 Ă  3 niveaux de profondeur.

Mobile First

Le Mobile First est un principe de conception qui recommande de concevoir une interface utilisateur en priorité pour les petits écrans, tels que les smartphones, puis d'adapter et d'étendre aux écrans plus grands, tels que les tablettes et les ordinateurs de bureau. En utilisant le des unités relatives comme %, em(unité de mesure longueur des espaces), ou rem(root em) pour la mise en page et la typographie. ou utilisation Flexbox ou Grid CSS pour créer des grilles qui s'adaptent à différentes tailles d'écran.

Raisons principales d'utiliser le Mobile First :

  • La majoritĂ© du trafic web est mobile: Aujourd'hui, une grande partie des utilisateurs accède Ă  Internet via leur smartphone. Concevoir d'abord pour mobile garantit une bonne expĂ©rience pour la majoritĂ©.
  • Meilleure performance: Le Mobile First pousse Ă  charger uniquement les Ă©lĂ©ments essentiels. Cela rend les pages plus rapides, surtout sur des connexions mobiles (3G/4G).
  • SimplicitĂ© et priorisation du contenu: Les petits Ă©crans obligent Ă  aller Ă  l'essentiel. Cela aide Ă  mieux hiĂ©rarchiser l'information, ce qui profite aussi aux versions desktop.

Pixel perfect

Pixel perfect, ça veut dire que l'interface développée correspond exactement au design fourni, au pixel près.mêmes espacements, mêmes tailles de police, mêmes couleurs, mêmes alignement.

L'UI est fidèle à la maquette.

Je m'assure du pixel perfect avec: précision dès le développement, vérification visuelle avec Design on fait review design, et outils adaptés.

Use client

Cette directive est utilisée pour indiquer que certains composants ou parties du code doivent être exécutés côté client uniquement. Elle permet de s'assurer que certains comportements interactifs, dépendants du navigateur ou des APIs web spécifiques au client, sont traités au bon endroit.

Avantages :

  • Gestion de l'Ă©tat et des effets (hooks React) : use client permet l'utilisation de hooks comme useState ou useEffect, qui ne peuvent pas fonctionner cĂ´tĂ© serveur. Cela est essentiel pour gĂ©rer des interactions et des mises Ă  jour d'UI basĂ©es sur des Ă©vĂ©nements utilisateur.
  • InteropĂ©rabilitĂ© avec des bibliothèques du client : Certaines bibliothèques (comme des animations ou des graphiques interactifs) nĂ©cessitent d'ĂŞtre exĂ©cutĂ©es cĂ´tĂ© client, car elles dĂ©pendent du DOM ou d'Ă©lĂ©ments spĂ©cifiques au navigateur.
  • Optimisation du rendu : Avec use client, ces composants seront chargĂ©s seulement au moment nĂ©cessaire, rĂ©duisant la charge initiale du serveur.

Use server

Cette directive est au cœur de la stratégie de rendu côté serveur (SSR) dans Next.js. Elle permet de spécifier que certains composants ou morceaux de logique sont exclusivement exécutés côté serveur.

Avantages :

  • Accès aux donnĂ©es cĂ´tĂ© serveur : use server est utile pour rĂ©cupĂ©rer des donnĂ©es sensibles ou spĂ©cifiques au serveur (comme une base de donnĂ©es ou des API sĂ©curisĂ©es). Cela permet de sĂ©curiser la logique mĂ©tier ou la gestion des donnĂ©es.
  • Optimisation des performances : En sĂ©parant les composants qui peuvent ĂŞtre rendus cĂ´tĂ© serveur, on peut diminuer la quantitĂ© de JavaScript envoyĂ©e au client, rĂ©duisant ainsi le temps de chargement initial et amĂ©liorant l'expĂ©rience utilisateur.
  • Simplification du code cĂ´tĂ© serveur : Au lieu d'avoir Ă  gĂ©rer manuellement ce qui doit ĂŞtre rendu cĂ´tĂ© client ou serveur, la directive use server permet d'indiquer explicitement que ce code ne sera jamais envoyĂ© au client. Cela clarifie les responsabilitĂ©s entre les deux cĂ´tĂ©s de l'application.

Challenge optimisation

Dans ma mission précédente, je travaillais sur une application à fort trafic qui devait être rapide et fluide, Comme on a des composants visuels lourds comme des animations et des graphiques interactifs. La complexité augmentait avec l'utilisation de plusieurs librairie et la grande quantité de données à afficher.

Pour résoudre ce problème, j'ai adopté plusieurs approches tels que

L'optimisation du rendu côté client

  • Lazy Loading et Code Splitting : J'ai implementĂ© la technique de "lazy loading", les composants n'Ă©taient chargĂ©s lorsqu'ils Ă©taient rĂ©ellement nĂ©cessaires, ça reduit la charge initiale. J'ai utilisĂ© le "code splitting" pour diviser les bundles JavaScript en fichiers plus petits et spĂ©cifiques, ce qui permettait d'amĂ©liorer la performance l'application
  • MĂ©moĂŻsation avec React (useMemo, useCallback) : pour Ă©viter des rendus inutiles, lors de l'interaction avec des composants rĂ©actifs.

Optimisation de la gestion de l'état global (Redux)

Pour l'application Mynexity, on a auparavant un state global qui contient beaucoup de données partagées entre différents composants. Pour réduire l'encombrement du store et éviter des rerendering inutiles, j'ai mis en place plusieurs optimisations :

  • Localisation de l'Ă©tat : J'ai analysĂ© les donnĂ©es pour dĂ©terminer lesquelles devaient rĂ©ellement ĂŞtre partagĂ©es globalement. Lorsque possible, j'ai mis comme state lau niveau des composants pour allĂ©ger le state global.
  • Caching et SĂ©lecteurs (Reselect et Cache Invalidation) : J'ai utilisĂ© des sĂ©lecteurs mĂ©moĂŻsĂ©s via Reselect pour Ă©viter de recalculer des sĂ©lecteurs lorsque les donnĂ©es n'avaient pas changĂ©. Et l'ulisation d'invalidation de cache pour maintenir le state Ă  jour sans affecter les performances.

Analyse des performances : J'ai utilisé des outils comme Lighthouse et Chrome DevTools pour identifier les goulets d'étranglement au niveau des temps de chargement, et j'ai optimisé les assets (minification, compression des images, etc.) et réduit le nombre de requêtes réseau.

Collaboration inter-équipe : Pour bien structure bien les données j'ai travaillé avec les développeurs back-end pour améliorer les APIs et limiter les appels redondants et de mieux paginer les données envoyées au front.

Refactoring de code: L'un des aspects les plus délicats dans une mission que j'ai réalisée a été la refactorisation de code sans tests, avec une structure de code mal organisée. En, j'ai adopté une approche progressive tels que la mise en place de:

  • Tests Snapshots : J'ai choisi des tests de snapshot pour m'assurer que les modifications dans les composants n'affectaient pas de manière imprĂ©vue le rendu visuel ou fonctionnel. Ça me permet de faire la refacto et d'assurer que mes modifications ne provoquent pas de rĂ©gressions.
  • Mise en place de tests unitaires et d'intĂ©gration : En plus des snapshots, j'ai mis en place des tests unitaires et d'intĂ©gration au fur et Ă  mesure sur les parties critiques du code.CelĂ  permis d'amĂ©liorer la couverture de tests, et avoir aussi de crĂ©er une base solide

Throttling Vs debouncing

  • Throttling : limite l'exĂ©cution d'une fonction Ă  un appel toutes les X ms.
  • Debouncing : attend une pĂ©riode d'inactivitĂ© pour exĂ©cuter la fonction.

Utilisation :

  • Throttle : scroll, resize events.
  • Debounce : input search, autocomplete.

Feature fiere

Le feature dont je suis le plus fier, c'est le développement fullstack du module de rendez-vous pour la téléconsultation. J'ai géré à la fois le frontend avec Next.js et Material UI, et le backend en NestJS avec Postgres. Le module couvrait la sélection de créneaux en temps réel, la synchronisation avec les calendriers des médecins, le paiement via Stripe, l'envoi de notifications et la sécurisation par OTP.

Côté complexité, le premier défi majeur a été la gestion des conflits de réservation. Pour éviter que deux patients réservent le même créneau simultanément, j'ai mis en place une vérification serveur qui contrôle la disponibilité du créneau en base. En cas de conflit, l'API rejette la demande avec une erreur claire. Pour fiabiliser ça en cas d'accès concurrent, j'ai encapsulé la logique dans une transaction SQL avec un niveau d'isolation SERIALIZABLE, ce qui garantit qu'aucun double booking ne peut se produire. En complément, on a ajouté un verrouillage temporaire des créneaux pendant le paiement pour améliorer l'expérience utilisateur.

Le second défi a été la gestion des fuseaux horaires entre patients et médecins. J'ai normalisé toutes les dates au format UTC côté backend et base de données, puis le frontend convertit dynamiquement ces dates en heure locale via le fuseau horaire du navigateur. Ça permet une gestion fiable, cohérente, et sans bug, même en cas de changement d'heure ou si le médecin et le patient sont dans des pays différents."

Accessibilité

Objectif : rendre le web utilisable par tous, y compris les personnes en situation de handicap.

Bonnes pratiques :

  • Utiliser les balises HTML sĂ©mantiques (\<nav>, \<header>, \<main>, etc.).
  • GĂ©rer correctement le focus clavier (ex. : avec tabindex, aria-*).
  • Fournir des alternatives textuelles (alt sur les images, aria-label).
  • S'assurer que les contrastes de couleurs sont suffisants.
  • Tester avec des lecteurs d'Ă©cran (NVDA, VoiceOver).

Mon approche sur l'accessibilité

Je travaille sur trois axes :

  • sĂ©mantique : structure HTML correcte, rĂ´les natifs privilĂ©giĂ©s
  • interaction : navigation clavier, focus management, pièges Ă  focus maĂ®trisĂ©s
  • perception : contrastes, feedback, libellĂ©s, erreurs comprĂ©hensibles

Je cherche à rendre les composants accessibles par défaut, au niveau du design system, pour éviter de redécouvrir les mêmes problèmes feature par feature.

J'ai travaillé sur l'accessibilité de l'application pour assurer qu'elle soit utilisable par tous les utilisateurs, y compris ceux utilisant des technologies d'assistance.

Concrètement, j'ai :

  • ajoutĂ© des attributs ARIA pour amĂ©liorer la comprĂ©hension des composants interactifs
  • vĂ©rifiĂ© la navigation au clavier (tab, focus visible, ordre logique)
  • amĂ©liorĂ© les contrastes de couleurs pour respecter les standards WCAG
  • utilisĂ© des balises HTML sĂ©mantiques (header, nav, main, button…)
  • ajoutĂ© des labels et descriptions pour les formulaires
  • testĂ© avec des lecteurs d'Ă©cran pour valider l'expĂ©rience

L'objectif était de rendre l'interface plus inclusive et conforme aux bonnes pratiques d'accessibilité.

Outils :

  • Lighthouse (audit accessibilitĂ©)
  • axe DevTools
  • Testing Library avec toBeAccessible() (via jest-axe)

Défis techniques rencontrés & solutions

  • Composants personnalisĂ©s (modales, dropdowns, autocomplĂ©tion)

Problème : Les composants custom n'ont pas de comportement natif clavier ou lecteur d'écran.

Solution : Suivre les [WAI-ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/) pour le rôle, le focus, les touches (ESC, flèches). Exemple : pour une modale, ajouter : role="dialog" aria-modal="true" focus piégé à l'intérieur ESC pour fermer

  • Changement de page sans rechargement (SPA/Next.js)

Problème: Le lecteur d'écran ne perçoit pas qu'une nouvelle page est chargée.

Solution: Utiliser un aria-live region pour annoncer le changement de contenu. Gérer le focus à chaque navigation (focus main content). document.getElementById('main-content')?.focus();

  • Internationalisation & accessibilitĂ©

Problème : Certains attributs (aria-label, title) sont codés en dur → problèmes multilingues.

Solution : Utiliser i18n aussi pour les attributs ARIA :

\<button aria-label={t('accessibility.openMenu')}>{t('menu')} \</button>

  • Gestion des focus dans les composants dynamiques

Problème : Sur le projet BNP Paribas, certaines modales et dropdowns étaient créés dynamiquement. Lors de l'ouverture, le focus ne se déplaçait pas correctement → les utilisateurs clavier perdaient la navigation.

Solution : J'ai mis en place un focus trap (soit avec focus-trap-react, soit en le codant manuellement) pour limiter la navigation clavier Ă  la modale ouverte, et restaurer le focus Ă  la fermeture.

Difficulté : Il fallait gérer les cas où plusieurs modales ou overlays pouvaient être ouverts en cascade.

  • AccessibilitĂ© des composants custom (UI non natifs)

Problème : on utilisait des composants Material UI et certains étaient surchargés pour le design → perte de sémantique (ex. un \<div> faisait office de bouton).

Solution : J'ai veillé à ce que ces composants custom : soient cliquables et accessibles au clavier (onKeyDown + tabIndex=0), aient un rôle correct (role="button") et un aria-pressed ou aria-expanded si nécessaire.

Difficulté : Éviter de casser le style tout en gardant la logique d'accessibilité intacte.

  • Composants dynamiques et annonces pour lecteurs d'Ă©cran

Problème : Certaines notifications (success/error) n'étaient pas annoncées par les lecteurs d'écran.

Solution : J'ai ajouté des régions aria-live (aria-live="assertive") pour forcer les lecteurs d'écran à annoncer les changements de statut.

Difficulté : Éviter les annonces en double quand plusieurs événements se déclenchaient simultanément.

Version plus poussée

L'accessibilité ne se limite pas à respecter quelques règles techniques, c'est un vrai travail d'équipe et un processus continu.

Sur mes projets, j'essaie d'aller plus loin :

  • IntĂ©gration dans le design system : avec Storybook, on a documentĂ© les composants accessibles (boutons, formulaires, modales) afin que toute l'Ă©quipe puisse les rĂ©utiliser sans recrĂ©er de dettes techniques.
  • Collaboration avec l'UX/UI : dès la conception, je participe aux discussions pour m'assurer que les maquettes respectent les contrastes, la hiĂ©rarchie visuelle et l'ergonomie clavier.
  • Revues de code focalisĂ©es sur l'accessibilitĂ© : pendant les code reviews, je vĂ©rifie les labels, le focus, les rĂ´les ARIA, et je propose des amĂ©liorations si besoin.
  • Tests automatiques : j'intègre des outils comme jest-axe ou les add-ons Storybook accessibility pour dĂ©tecter automatiquement les problèmes avant la mise en production.
  • Sensibilisation de l'Ă©quipe : je partage rĂ©gulièrement des bonnes pratiques et des retours d'expĂ©rience pour que l'accessibilitĂ© devienne un rĂ©flexe collectif.

Sécurité

Objectif : éviter les vulnérabilités côté client.

Risques communs en front-end :

  • XSS (Cross-Site Scripting) : Ă©viter d'injecter du HTML via innerHTML sans sanitation.
  • CSRF : bien que souvent gĂ©rĂ© cĂ´tĂ© serveur, ĂŞtre conscient des requĂŞtes sensibles.
  • Exposition de donnĂ©es sensibles dans le code client : ne jamais embarquer de secrets/API keys non publiques.

Bonnes pratiques :

  • Utiliser un CSP (Content Security Policy).
  • Éviter les dĂ©pendances non maintenues ou malveillantes (vĂ©rifier avec npm audit).
  • Échapper/sanitizer toutes les entrĂ©es utilisateurs.

Comportement navigateur lorsqu'un utilisateur tape XXX dans la barre d'adresse de son navigateur et appuie sur Entrée

1. Résolution DNS (Domain Name System): Le navigateur demande : « Quelle est l'adresse IP de xxxx.com ? » Il consulte d'abord son cache DNS local. Sinon, il demande à un serveur DNS (souvent celui du FAI ou de Google/Cloudflare). Résultat : il reçoit une adresse IP, ex. 192.0.2.1.

2. Connexion TCP + Sécurisation via HTTPS (TLS/SSL): Le navigateur ouvre une connexion TCP avec le serveur IP. Ensuite, il effectue une négociation TLS (si HTTPS) pour établir une connexion sécurisée. Certificat SSL est vérifié ici :

Est-il valide ? ou Expiré ? et Correspond-il bien à l'adresse XXX.fr ?

En front : → Si le certificat est invalide, le navigateur bloque l'accès avant même de charger le HTML.

3. Envoi de la requête HTTP Une fois connecté, le navigateur envoie une requête HTTP

4. Réponse du serveur

Le serveur retourne les contenues. Le navigateur commence à parser le HTML dès les premiers octets reçus.

5. Parsing et rendu HTML + ressources

Le navigateur commence à construire le DOM (Document Object Model). Il repère ensuite : Les feuilles de style CSS → Téléchargées et appliquées. Les scripts JavaScript → Exécutés (sauf si defer ou async). Les images, polices, iframes, etc.

En front : → Un JS bloquant (\<script> sans defer) peut bloquer le rendu. → Mauvais chargement des polices \= problème UX. → meta tags impactent SEO et accessibilité (lang, viewport, etc.).

6. Hydratation (si React/Next.js)

Si c'est un site en React SSR (comme Next.js) : Le HTML est d'abord rendu côté serveur. Ensuite, React hydrate ce contenu côté client : il attache les événements, active les composants interactifs.

Test composant

En React, je distingue trois types principaux de tests :

1. Tests unitaires : je teste des composants ou fonctions isolés. J'utilise généralement Jest avec React Testing Library. Par exemple, je peux tester qu'un bouton affiche bien un texte ou qu'une fonction utilitaire retourne le bon résultat.

2. Tests d'intégration : je vérifie que plusieurs composants fonctionnent bien ensemble. Par exemple, je teste qu'un formulaire affiche une erreur quand on soumet un champ vide. J'utilise aussi React Testing Library ici, car elle simule bien l'interaction utilisateur.

3. Tests end-to-end (E2E) : je simule le comportement de l'utilisateur dans le navigateur. Pour ça, j'utilise Cypress (ou parfois Playwright). Je teste le parcours complet : par exemple, un utilisateur qui se connecte, ajoute un produit au panier, puis valide la commande.

Comment on fait le test composant

Quand je teste un composant React, je privilégie les tests d'intégration, même si parfois je fais aussi des tests unitaires.

En fait, avec React Testing Library, on est encouragé à tester le composant comme un utilisateur l'utiliserait, donc en simulant les interactions (clic, saisie, etc.), ce qui rend le test plus proche de la réalité. C'est plus un test d'intégration qu'unitaire.

Exemple : si j'ai un composant LoginForm avec deux champs et un bouton, je ne vais pas tester chaque champ individuellement (test unitaire), mais plutôt vérifier que l'ensemble fonctionne bien : l'utilisateur remplit les champs, clique sur "Se connecter", et je vérifie que l'action correcte est déclenchée.

J'utilise Jest + React Testing Library pour ça. Je peux mocker les fonctions externes (comme les appels API ou les hooks custom) si besoin.

J'écris des tests unitaires seulement quand j'ai une logique isolée, par exemple une fonction utilitaire ou un hook personnalisé.

Best Practices de Sécurité

  • Éviter les failles XSS (Cross-Site Scripting)

React protège par défaut contre le XSS, mais tu peux encore te piéger si tu désactives cette protection.

Bonnes pratiques :

  • Ne jamais utiliser dangerouslySetInnerHTML sauf cas ultra-contrĂ´lĂ©.
  • Ne rends jamais du HTML dynamique non filtrĂ© (par exemple depuis l'utilisateur).
  • Si tu dois afficher du HTML : utilise une lib de "sanitization" comme [DOMPurify](https://github.com/cure53/DOMPurify).
  • Stockage sĂ©curisĂ© des tokens (authentification)

Les tokens JWT ou autres ne doivent jamais être stockés dans localStorage ou sessionStorage pour des apps sensibles.

Meilleure approche :

Stocke le token dans un cookie HTTP-only, configuré avec : - HttpOnly: true - Secure: true - SameSite: Strict - Cela empêche tout accès via JavaScript → protection contre le XSS.

  • SĂ©curiser les appels API

Bonnes pratiques :

  • Utilise HTTPS uniquement
  • Ne stocke pas d'info sensible cĂ´tĂ© client
  • Ne laisse pas les endpoints exposĂ©s sans vĂ©rification cĂ´tĂ© backend
  • ImplĂ©mente rate limiting et authentification forte (JWT, OAuth, etc.)

Content-Security-Policy (CSP)

La Content-Security-Policy (CSP) est un en-tête de sécurité HTTP qui permet au serveur de contrôler les sources de contenu qu'un navigateur est autorisé à charger pour une page web. But principal : Empêcher les attaques XSS, les injections de scripts et le chargement de contenu malveillant.

Attaque XSSF ou CRSF

XSS (Cross-Site Scripting) : Une attaque XSS permet à un attaquant d'injecter du code JavaScript malveillant dans des pages web consultées par d'autres utilisateurs.

CSRF (Cross-Site Request Forgery) : Une attaque CSRF consiste à induire un utilisateur légitime à exécuter des actions non désirées sur un site, il est authentifié, sans son consentement.

Côté Front-End (Client)

Échapper les Entrées Utilisateur

  • Utilisez des techniques comme l'Ă©chappement HTML pour dĂ©sactiver le code JavaScript potentiellement malveillant avant d'afficher du contenu utilisateur. Par exemple, en utilisant des bibliothèques comme DOMPurify pour nettoyer les entrĂ©es.

Validation Côté Client

  • Validez et filtrez les donnĂ©es cĂ´tĂ© client pour dĂ©tecter les scripts malveillants ou les caractères non autorisĂ©s avant de les soumettre au serveur.

Headers de Sécurité

  • Utilisez des en-tĂŞtes HTTP comme Content-Security-Policy (CSP) pour restreindre les sources de contenu autorisĂ©es (comme les scripts et les styles) et rĂ©duire les risques d'exĂ©cution de scripts malveillants.

Utilisation de Cookies Sécurisés

  • Utilisez l'attribut SameSite pour les cookies afin de limiter les attaques CSRF en empĂŞchant les navigateurs de renvoyer automatiquement les cookies lors des requĂŞtes cross-site.

Compatibilités entre différents navigateurs

Pour gérer les compatibilités sont:

  • Il est essentiel de respecter les normes du W3C pour assurer que les sites web fonctionnent de manière cohĂ©rente sur tous les navigateurs et appareils.

Principales Normes Web du W3C

  • HTML (HyperText Markup Language) :Objectif : Structurer le contenu des pages web avec des Ă©lĂ©ments comme les titres, les paragraphes, les liens, les images, etc.
  • CSS (Cascading Style Sheets) :Objectif : SĂ©parer la prĂ©sentation du contenu pour un design plus flexible et maintenable.
  • JavaScript et DOM (Document Object Model) :JavaScript : Le langage de programmation utilisĂ© pour crĂ©er du contenu dynamique sur les pages web.
  • Utiliser des Outils de PrĂ©processeur et de Postprocesseur

Autoprefixer : Ajoute automatiquement les préfixes nécessaires pour les propriétés CSS afin de garantir la compatibilité avec différents navigateurs.

Babel : Transpile le JavaScript moderne en une version compatible avec les navigateurs plus anciens.

  • Polyfills: Pour ajouter des fonctionnalitĂ©s modernes aux navigateurs plus anciens qui ne les prennent pas en charge. Par exemple, core-js et polyfill.io
  • Responsive Design: on utilise les fonctions media query, tailwinds

function currying

Le currying est une technique qui transforme une fonction à plusieurs arguments en une chaîne de fonctions, chacune prenant un seul argument (ou un sous-ensemble d'arguments).

Pourquoi ça apparaît en React

  • a) Passage de paramètres aux handlers
  • En React, quand on veut donner des paramètres Ă  un onClick ou autre event handler, on peut utiliser une fonction curryfiĂ©e pour Ă©viter les .bind ou les fonctions anonymes lourdes.
  • b) Partage de logique entre composants
  • Avec le currying, on peut crĂ©er des fonctions rĂ©utilisables qui capturent un contexte et renvoient une fonction adaptĂ©e.

Avantages en React

  • ClartĂ© : chaque fonction ne gère qu'une seule "responsabilitĂ©" (capturer un paramètre, ou gĂ©rer l'event).
  • RĂ©utilisabilitĂ© : tu peux prĂ©configurer une fonction pour diffĂ©rents composants.
  • Évite bind : pas besoin de .bind(this, arg) ou de recrĂ©er des fonctions anonymes en JSX.

TanStack query

TanStack Query c'est une librairie qui permet de simplifier la gestion des données côté client car il nous gèrele cache, le refetch, les états de chargement/erreur et même l'invalidation après mutation. Résultat : moins de code useEffect/useState, des données toujours fraîches, et une meilleure UX grâce au cache et au background refresh.

Ce qu'apporte TanStack Query :

  • Cache & synchronisation automatique: Stocke les rĂ©ponses API par queryKey, rĂ©utilise les donnĂ©es quand on revient sur une page. et Évite les requĂŞtes inutiles (deduplication).
  • Mise Ă  jour en arrière-plan (stale-while-revalidate): Affiche les donnĂ©es du cache immĂ©diatement, puis refetch en arrière-plan pour rafraĂ®chir. UX plus fluide (pas d'Ă©cran vide Ă  chaque navigation).
  • Gestion des Ă©tats intĂ©grĂ©e: isLoading, isError, isFetching, isStale → plus besoin de les coder Ă  la main.
  • Invalidation ciblĂ©e: Après une mutation (POST/PUT/DELETE), on peut invalider prĂ©cisĂ©ment les queries impactĂ©es → donnĂ©es toujours cohĂ©rentes.

staleTime définit combien de temps une donnée est considérée fraîche avant d'être marquée comme "stale" et donc potentiellement refetchée.

exemple: staleTime: 10_000 → si on revient sur la page dans les 10s, les données s'affichent directement sans refetch.

gcTime définit combien de temps la donnée reste en mémoire après qu'il n'y a plus d'abonnés (composants montés) avant d'être supprimée du cache.

exemple: gcTime: 5 * 60_000 → les données restent 5 min en mémoire même si on change de page.

WAF

WAF (Web Application Firewall) : Un pare-feu applicatif web (WAF) est un dispositif de sécurité (logiciel ou matériel) placé devant une application web pour filtrer, surveiller et bloquer le trafic HTTP malveillant.

Rôle : Il protège les applications web contre les attaques courantes comme :

  • Injection SQL
  • Cross-Site Scripting (XSS)
  • Cross-Site Request Forgery (CSRF)
  • Exploitation de vulnĂ©rabilitĂ©s connues

Fonctionnement : Le WAF analyse les requêtes HTTP/HTTPS entrantes et sortantes selon des règles de sécurité (signatures, comportement, listes noires/blanches).

OWASP (Open Web Application Security Project)

L'OWASP est une organisation internationale à but non lucratif qui œuvre pour améliorer la sécurité des applications web.

RĂ´le principal :

  • Publier des guides, outils et ressources pour les dĂ©veloppeurs et les entreprises.
  • Le plus connu est le OWASP Top 10, une liste des 10 principales failles de sĂ©curitĂ© web (mise Ă  jour rĂ©gulièrement).

Exemples de failles OWASP Top 10 :

  • A01: Injection
  • A02: Mauvaise gestion de l'authentification A03: Exposition de donnĂ©es sensibles
  • A05: Mauvaise configuration de sĂ©curitĂ©
  • A04: Insecure Design (Conception non sĂ©curisĂ©e) : Exemple : Une application de e-commerce qui ne limite pas le nombre de tentatives de paiement, permettant des attaques par force brute.
  • A05: Security Misconfiguration (Mauvaise configuration de sĂ©curitĂ©) Exemple : Un serveur web expose les pages d'administration par dĂ©faut (/phpmyadmin) sans ĂŞtre protĂ©gĂ©es.
  • A06: Vulnerable and Outdated Components (Composants vulnĂ©rables ou obsolètes): Exemple : Utiliser une ancienne version de Struts ou WordPress avec des failles connues et non corrigĂ©es.
  • A07: Identification and Authentication Failures (DĂ©faillances d'authentification): Exemple : Mots de passe faibles acceptĂ©s (123456) ou absence de double authentification (MFA).
  • A08: Software and Data Integrity Failures (DĂ©faillances d'intĂ©gritĂ© logicielle et des donnĂ©es) Exemple : TĂ©lĂ©chargement automatique d'une mise Ă  jour sans vĂ©rifier la signature → possibilitĂ© d'injecter un malware.
  • A09: Security Logging and Monitoring Failures (DĂ©faillances de journalisation et de surveillance): Exemple : Aucune alerte n'est gĂ©nĂ©rĂ©e après 1000 tentatives de connexion Ă©chouĂ©es → attaque par brute force indĂ©tectĂ©e.
  • A10: Server-Side Request Forgery (SSRF – falsification de requĂŞtes cĂ´tĂ© serveur): Exemple : Une application permet de tĂ©lĂ©charger une image depuis une URL fournie par l'utilisateur, mais sans validation → un attaquant peut accĂ©der Ă  http://localhost:8080/admin.

Http

HTTP (HyperText Transfer Protocol) est un protocole de communication utilisé pour échanger des informations sur le web. C'est le protocole, permettant à un client (comme un navigateur web) de demander des ressources à un serveur (comme une page web, une image ou une API).

Comment fonctionne HTTP ?

HTTP suit un modèle requête-réponse où :

Le client (exemple : un navigateur web ou une application) envoie une requĂŞte HTTP au serveur.

Le serveur traite la requête et envoie une réponse HTTP.

RequĂŞte HTTP :

La requĂŞte contient plusieurs parties :

  • MĂ©thode HTTP : Indique l'action demandĂ©e. Exemples :

GET : Récupérer une ressource (comme une page ou une image).

POST : Envoyer des données au serveur (comme un formulaire ou une API).

PUT : Mettre Ă  jour ou remplacer une ressource.

DELETE : Supprimer une ressource.

  • URL (Uniform Resource Locator) : SpĂ©cifie la ressource demandĂ©e.
  • En-tĂŞtes (Headers) : MĂ©tadonnĂ©es sur la requĂŞte (type de contenu, authentification, etc.).
  • Corps (Body) : Contenu de la requĂŞte, utilisĂ© surtout avec POST ou PUT.

Https

HTTPS (HyperText Transfer Protocol Secure) est une version sécurisée du protocole HTTP. Il ajoute une couche de chiffrement et d'authentification grâce au protocole SSL/TLS (Secure Sockets Layer/Transport Layer Security), garantissant que les données échangées entre le client (navigateur) et le serveur restent confidentielles et intègres.

Comment HTTPS fonctionne ?

HTTPS combine le fonctionnement de HTTP avec une couche de sécurité par SSL/TLS.

Le client et le serveur établissent une connexion sécurisée et le certificat SSL/TLS est échangé pour authentifier le serveur.

Une clé de session (clé symétrique) est générée et utilisée pour chiffrer les données échangées.:

Toutes les communications HTTP normales (requêtes et réponses) se font à travers cette connexion sécurisée.

Http 1 VS 2

HTTP 1

  • Les requĂŞtes et rĂ©ponses sont envoyĂ©es une Ă  la fois sur une connexion TCP.
  • Pour charger plusieurs ressources simultanĂ©ment, il est nĂ©cessaire d'ouvrir plusieurs connexions parallèles (souvent limitĂ©es Ă  6 connexions par domaine dans les navigateurs).
  • Cela peut entraĂ®ner une surcharge rĂ©seau et un ralentissement.

HTTP 2

  • Permet le multiplexage, c'est-Ă -dire plusieurs requĂŞtes et rĂ©ponses envoyĂ©es simultanĂ©ment sur une seule connexion TCP.
  • Les ressources sont chargĂ©es plus rapidement sans nĂ©cessitĂ© d'ouvrir plusieurs connexions.

HTTP/1.1 :

  • Les en-tĂŞtes HTTP sont envoyĂ©s en texte brut Ă  chaque requĂŞte.
  • Les mĂŞmes en-tĂŞtes sont souvent rĂ©pĂ©tĂ©s pour plusieurs requĂŞtes (comme les cookies, les User-Agent, etc.), ce qui augmente inutilement la taille des donnĂ©es.

HTTP/2 :

  • Utilise le protocole HPACK pour compresser les en-tĂŞtes.
  • Les en-tĂŞtes redondants ne sont pas retransmis, rĂ©duisant ainsi la surcharge.

Certificat SSL/TLS ?

Un certificat SSL/TLS est un fichier électronique émis par une autorité de certification (CA, Certificate Authority).

Il contient :L'identité du propriétaire (nom de domaine, organisation, etc.).Une clé publique pour établir une connexion sécurisée.Une signature numérique de l'autorité de certification.

Fonctionnement :

Lorsqu'un client (navigateur) se connecte à un site HTTPS, il demande le certificat SSL/TLS.Le certificat est vérifié par le navigateur pour s'assurer qu'il est valide et qu'il provient d'une autorité de confiance.Une connexion sécurisée est établie si tout est en ordre.

CORS

CORS ou (Cross-Origin Resource Sharing) est un mécanisme de sécurité qui permet aux serveurs de contrôler les requêtes provenant de domaines externes. CORS peut être configuré avec le middleware cors pour Express, en spécifiant les domaines autorisés, les méthodes, et les en-têtes. Cela protège contre les requêtes non autorisées provenant d'autres origines.

Il protège les utilisateurs contre les attaques malveillantes comme le Cross-Site Request Forgery (CSRF).

JWT

JWT(JSON WEB TOKEN) est composé de trois parties séparées par des points (.) : header, payload et la signature. Chaque partie est encodée en Base64 pour former un jeton compact.

En-tête (Header) :Contient des métadonnées sur le type de jeton et l'algorithme de signature utilisé pour le sécuriser.

Payload (Charge Utile) : Contient les données réclamées (claims) que le JWT transporte. Il existe trois types de claims(réclamations) : réservées, publiques et privées

Signature : Utilisée pour vérifier que le JWT n'a pas été modifié ou falsifié pendant son transit entre les parties. La signature est calculée à l'aide d'un algorithme headers (par exemple, HMAC SHA-256 ou RSA)

Protection de JWT

Chiffrement des Réclamations :

  • Pour protĂ©ger les donnĂ©es sensibles, les rĂ©clamations peuvent ĂŞtre chiffrĂ©es avant d'ĂŞtre ajoutĂ©es au JWT. Cela assure leur confidentialitĂ© mĂŞme si le JWT est dĂ©codĂ© par des parties non autorisĂ©es.

Utilisation de Clés Secrètes :

  • Pour les JWT signĂ©s (non chiffrĂ©s), une clĂ© secrète partagĂ©e est utilisĂ©e pour gĂ©nĂ©rer et vĂ©rifier la signature. Cette clĂ© doit ĂŞtre gardĂ©e confidentielle pour empĂŞcher la falsification des JWT.

Expiration et Renouvellement :

  • Les JWT peuvent inclure une date d'expiration (exp) pour limiter leur durĂ©e de validitĂ©. Après expiration, ils ne sont plus valides et doivent ĂŞtre renouvelĂ©s en gĂ©nĂ©rant un nouveau JWT.

Validation Côté Serveur :

  • Lorsque le serveur reçoit un JWT, il vĂ©rifie la signature pour s'assurer que le JWT est authentique et n'a pas Ă©tĂ© modifiĂ©. Il vĂ©rifie Ă©galement les rĂ©clamations pour dĂ©cider de la suite des actions.

Utilisation de JWT

Authentification et Autorisation :

  • JWT est utilisĂ© pour l'authentification des utilisateurs après la connexion initiale. Une fois authentifiĂ©s, les utilisateurs peuvent prĂ©senter le JWT comme preuve de leur identitĂ© pour accĂ©der aux ressources protĂ©gĂ©es.

APIs et Services Web :

  • JWT est largement utilisĂ© dans les APIs et les services web oĂą il est utilisĂ© comme mĂ©canisme de jeton d'accès sĂ©curisĂ© pour contrĂ´ler l'accès aux ressources et aux fonctionnalitĂ©s.

Flex Vs Grid

Flexbox(container et Flex items)

Flexbox est un modèle de disposition unidimensionnelle. C'est-à-dire qu'il peut gérer une seule dimension à la fois : soit en colonne soit en ligne. Ce modèle va permettre de distribuer l'espace entre des objets d'une interface ainsi que de les aligner.

CSS Grid layout

Le module CSS Grid layout (modèle de disposition en grille) qui permet la manipulation d'éléments dans une grille à deux dimensions. Les grilles peuvent être utilisées pour agencer des pages entières ou de petits éléments d'interface.

Contrairement à Flexbox, la grille n'a pas de structure de contenu. Les éléments « enfants » d'un conteneur en grille peuvent être positionnés afin qu'ils se chevauchent ou qu'ils se comportent comme des éléments positionnés.